Bash script For Cycle - bash

i´m new to scripting and bash.
I need help with bash script (for cycle)
I´ve got a script called for.sh
It has to ask 10 numbers from user with for cycle.
In every cycle number will be divided with 3 or 5.
If it divides it will say it.
My idea was to use read, for i in $(eval echo "$numbers") and if commands but that does not seem to work.

This can be achieved by for as well as while loop.
using for loop here:
#!/bin/bash
for (( i=1; i<=10; i++ ))
do
read -p "Enter the number:" num
if [[ $(($num%3)) -eq '0' ]]
then
echo "$num is divisible by 3"
elif [[ $(($num%5)) -eq '0' ]]
then
echo "$num is divisible by 5"
else
echo "$num is not divisible by either 3 or 5"
fi
done
I've initialized a variable i to 1, so everytime the for loop will run ,it'll ask the number from the user, store it into another variable called num and then check if the entered number is divisible by 3 or 5, if the entered number is not divisible by 3 or 5, it will say "number is not divisible by either 3 or 5".
With every run, the for loop will increment the count by 1 till it reaches the count=10.

Related

How do I write a Bash script for a C program that takes 4 numerical inputs? [duplicate]

This question already has answers here:
How to zero pad a sequence of integers in bash so that all have the same width?
(15 answers)
Closed 2 years ago.
I am writing a bash script for a c program, where the program asks for a 4 numerical pin inputs. However, when I wrote the script, the output seems to run in a loop, but it doesn't break where it gets identified as the correct number the program will accept.
#!/bin/bash
RANGE=9000
count=${RANDOM:0:4}
while [[ "$count" -le $RANGE ]]
do
number=$RANDOM
(( "number %= $RANGE" ))
echo $number
if [[ "$count" == "$RANGE" ]]; then
break
fi
done
When I run it, I can see some numbers in the output that returned as 2 or 3 digits, instead of 4. So in theory, what I want to do is find a random number that is 4 digits that the program will take, but I don't know what is the random number, so essentially it is a brute force, or just me manually guessing the pin number.
If all you need is a random 4-digit number, you can do that with:
printf -v number "%04d" $((RANDOM % 10000))
The $RANDOM gives you a random number 0..32767, the % 10000 translates that to the range 0..9999 (not perfectly distributed, but should be good enough for most purposes), and the printf ensures leading zeros are attached to it (so you'll see 0042 rather than 42, for example).
You can test it with the following script:
(( total = 0 ))
(( bad = 0 ))
for i in {1..10000} ; do
printf -v x "%04d" $((RANDOM % 10000))
(( total += 1 ))
[[ "${x}" =~ ^[0-9]{4}$ ]] || { echo Bad ${x}; (( bad += 1 )); }
done
(( good = total - bad ))
echo "Tested: ${total}, bad ${bad}, good ${good}"
which should give you:
Tested: 10000, bad 0, good 10000

monitor if variable is growing compared to others bash in the last readings

I'm doing a script in bash to monitor different changes to a variable ( a number). I want to get , let's say 10 readings, and determine if the number is growing, remaining the same or getting lower. The readings will be like : 1-2-4-3-6-7-9-8-6-9-7.... my script needs to know if the number is increasing or decreasing.
Store the previous value in a variable and compare the values numerically:
#! /bin/bash
for n in 1 2 4 3 3 6 7 9 8 6 9 7 ; do
echo $n
if [[ $previous ]] ; then
if (( previous < n )) ; then
echo Growing
elif (( previous > n )) ; then
echo Getting lower
fi
fi
previous=$n
done

Unix Scripting - Finding Minimum and Maximum (Bash Shell)

My code below is part of an assignment, but I'm racking my head against the desk not understanding why it won't assign a "MIN" value. I tried assigning the MIN and MAX to ${LIST[0]} just to have the first index in place, but it returns the whole array, which doesn't make sense to me. I'm executing this on a CentOS VM (which I can't see making a difference). I know the beginning of the first and second "if" statements need better logic, but I'm more concerned on the MIN and MAX outputs.
#!/bin/bash
LIST=()
read -p "Enter a set of numbers. " LIST
MIN=
MAX=
if [ ${#LIST[*]} == 0 ]; then echo "More numbers are needed."; fi
if [ ${#LIST[#]} -gt 0 ]; then
for i in ${LIST[#]}; do
if [[ $i -gt $MAX ]]; then
MAX=$i
fi
if [[ $i -lt $MIN ]]; then
MIN=$i
fi
done
echo Max is: $MAX.
echo Min is: $MIN.
fi
The code is almost functional.
Since $LIST is an array, not a variable, change read -p "Enter a set of numbers. " LIST to:
read -p "Enter a set of numbers. " -a LIST
Move the $MIN and $MAX init code down 5 lines, (just before the for loop):
MIN=
MAX=
...and change it to:
MIN=${LIST[0]}
MAX=$MIN
And it'll work. Test:
echo 3 5 6 | ./minmax.sh
Output:
Max is: 6.
Min is: 3.

bash - while loop - rolling 2 dice

I'm writing a bash script that rolls 2 dice(with 6 sides). When the 2 dice hits double sixes I want the script to stop (break) and count how many rolls it took to get double sixes.
#!/bin/bash
DOUBLESIX="6-6"
while (( 0 ==0 )) ; do
dice=$RANDOM; ((dice = dice % 6 )); (( dice = dice +1 ))
dice2=$RANDOM; ((dice2 = dice2 % 6 )); (( dice = dice + 1))
pair="$dice-dice$2"
echo $pair
if [[ "$pair" == "$DOUBLESIX" ]]; then
break
fi
done
echo "It took $count rolls to get 6-6 "
Here's what i have so far. Question is, how do I count how many times the while loop ran and put it in my $count?
Thanks in advance!
I won't comment too much on the other potential issues you have with your code, such as the dice$2 "variable", or the fact you can generate a random number between one and six inclusive with the somewhat simpler ((num = $RANDOM % 6 + 1)) - the learning process of fixing/improving those is what will make you a better coder.
But, for the specific question on how to maintain a count, that's relatively simple. Before the loop starts, insert the following code to initialise the count to zero:
((count = 0))
Then, with each roll of the two dice, use the following to increment the count:
((count = count + 1))
An example of how to do this can be seen below. It's for counting from one to ten but you should get the idea:
((count = 1))
while [[ ${count} -le 10 ]] ; do
echo $count
((count = count + 1))
done
For what it's worth (don't use this if this is a classwork problem, you'd be crazy to think educators don't search the net for plagiarism), here's how I would implement such a beast:
#!/bin/bash
DESIRED="6-6"
((count = 0))
dice="NOT ${DESIRED}"
while [[ "${dice}" != "${DESIRED}" ]] ; do
((count = count + 1))
((die1 = $RANDOM % 6 + 1))
((die2 = $RANDOM % 6 + 1))
dice="${die1}-${die2}"
echo ${dice}
done
echo "It took ${count} rolls to get ${DESIRED}"
I advice to use shuf for this purpose.
#!/bin/bash
declare -i count=1
while [ "6 6" != "$(shuf --input-range='1-6' -r -n 2 | xargs)" ]; do
(( ++count ))
done
echo "It took $count rolls to get double six."
To generating two random numbers between 1 and 6 we use
shuf --input-range='1-6' -r -n 2
shuf [OPTION]... [FILE] write a random permutation of the input lines to standard output. Each output permutation is equally likely. -i lo-hi or --input-range=lo-hi act as if input came from a file containing the range of unsigned decimal integers lo-hi, one per line. -r or --repeat repeat output values, that is, select with replacement. With this option the output is not a permutation of the input; instead, each output line is randomly chosen from all the inputs. -n count or --head-count=count output at most count lines (by default, all input lines are output). If --head-count is not given, shuf repeats indefinitely.
Type man shuf or see coreutils manual for more details.

Why is this bash program going into an infinite loop?

#!/bin/bash
echo "Enter number of loops"
read count
echo $count
if [ $count -eq 0 ]
then
echo "The count cannot be zero. Enter a number again"
read count
fi
while [ $count -gt 0 ]
do
echo "Loop numner $count"
count = `expr $count - 1`
done
I am trying to simulate a Java counter in bash. Does this exist?
You have space in between your assignment statement as below:
count = `expr $count - 1`
^ ^
Remove the space between "=" like below:
count=`expr $count - 1`
Output
Enter number of loops
10
10
Loop numner 10
Loop numner 9
Loop numner 8
Loop numner 7
Loop numner 6
Loop numner 5
Loop numner 4
Loop numner 3
Loop numner 2
Loop numner 1
Note apart, backticks are discouraged and you should be using something like:
count=$(expr $count - 1)
Here's a rock solid rewriting of your script, to show you how it's usually done:
#!/bin/bash
while true; do
read -rep "Enter number of loops: " count
if [[ $count = +([[:digit:]]) ]]; then
((count=10#$count))
((count>0)) && break
printf 'The count cannot be zero. Enter a number again.\n'
else
printf 'Please enter a valid number.\n'
fi
done
while ((count>0)); do
printf 'Loop number %s\n' "$count"
((--count))
done
Using read with the -r flag to have backslashes not escape some characters (this should be the default), with the -e option so that read uses readline: it's more comfortable for the user, and with the -p option to specify the prompt.
I completely revisited the logic you're using to read user's input: read is run in an infinite loop that can only be broken when user enters a valid number. With your method, a user could enter invalid data twice, and the loop would have run with random arguments. Not good.
To check that user input is valid, I'm using pattern matching: [[ $count = +([[:digit:]]) ]] that is true if and only if count expands to a string of one or more digits, then I'm making sure that Bash will treat count in radix 10: in arithmetic context, 10#$count treats count in radix 10. Without this, an input like 08 or 09 would make some subsequent parts fail, as a leading zero means, for Bash, that the number should be interpreted in radix 8, hence 08 is not valid!
The final loop is written with Bash's arithmetic context ((...)). You don't need the external expr to perform simple arithmetic.
You can also use bash arithmetic expansion:
count="$((count -1))"
I would also suggest making the first test -le not -eq, in case the user types in a negative integer, and quote it in case the user types nothing at all.
if [ "$count" -le 0 ]
So your code would be:
#!/bin/bash
echo "Enter number of loops"
read count
echo $count
if [ "$count" -le 0 ]
then
echo "The count cannot be zero. Enter a number again"
read count
fi
while [ $count -gt 0 ]
do
echo "Loop numner $count"
count="$((count - 1))"
done

Resources