This question already has answers here:
Arithmetic expressions in Bash?
(5 answers)
Closed 6 years ago.
I am doing a school assignment in bash and got this code:
if a < 0
a = a/b
else
a = b/a
fi
The assignment says that we need to divide two number read from the keyboard, and check if the first number is larger than the number 0.
echo "Write two numbers, with a space, that need to be divided:"
read a b
if a > 0
a = $a / $b
else
a = $b / $a
fi
echo "$a"
What am I doing wrong here?
Creating a math context in bash uses (( )). Note that bash only supports integer math natively -- be sure you aren't expecting fractional output (or using fractional inputs), and see BashFAQ #22 if this limitation is relevant to you.
if (( a > 0 )); then
a=$(( a / b ))
else
a=$(( b / a ))
fi
Related
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
This question already has answers here:
Bash command line and input limit
(4 answers)
Closed 4 years ago.
In a Bash script I am using a simple for loop, that looks like:
for i in $(seq 1 1 500); do
echo $i
done
This for loop works fine. However, when I would like to use a sequence of larger numbers (e.g. 10^8 to 10^12), the loop won't seem to start.
for i in $(seq 100000000 1 1000000000000); do
echo $i
done
I cannot imagine, that these numbers are too large to handle. So my question: am I mistaken? Or might there be another problem?
The problem is that $(seq ...) is expanded into a list of words before the loop is executed. So your initial command is something like:
for i in 100000000 100000001 100000002 # all the way up to 1000000000000!
The result is much too long, which is what causes the error.
One possible solution would be to use a different style of loop:
for (( i = 100000000; i <= 1000000000000; i++ )) do
echo "$i"
done
This "C-style" construct uses a termination condition, rather than iterating over a literal list of words.
Portable style, for POSIX shells:
i=100000000
while [ $i -le 1000000000000 ]; do
echo "$i"
i=$(( i + 1 ))
done
This question already has answers here:
How can I compare two floating point numbers in Bash?
(22 answers)
Closed 5 years ago.
I have a case like this:
string1="some_string"
string2="some_string"
int1="0.87"
int2="${var}"
$var is the output of some other script, and it has the form 0.994343123 or 0.3454657 or whatever (starts with 0. and the biggest value is around 0.9972343)
Now, I don't know how bash works, but usually string 0.87 is never less than or equal to 0.9999999, they are just different.
I would need something like this (pseudocode):
if (string1 equals string2 and int1 is less than int2):
do something;
else
do something else.
What i would expect is 0.87687 is greater than 0.87 (correct?? i was never good at math...)
Can anyone help me with the code for that if??
Thanks in advance!
Since bash does not handle floating point arithmetic, you may use bc -l to compare 2 floating point numbers and join the condition with && as:
if [[ $string1 = $string2 && $(bc -l <<< "$int1 < $int2") -eq 1 ]]; then
echo "yes"
else
echo "no"
fi
If the values are between 0 and 1, string comparison will work
s1=..; s2=..
v1="0.876"; v2="0.87"
[[ $s1 = $s2 && $v1 > $v2 ]] && echo yes || echo no
a=0.86
b=0.865
if ((`echo $a '<' $b|bc`)); then echo 'a<b'; fi
(You can replace the last line by
if (($(echo $a '<' $b|bc))); then echo 'a<b'; fi
but imho it is less readable)
This question already has answers here:
How do I compare two string variables in an 'if' statement in Bash? [duplicate]
(12 answers)
Closed 6 years ago.
Here is a random number generator followed by a line clear timer and you are then to try and input the number that you saw. I cant seem to set up the comparison between the randNum variable and the input. I tried setting a defined value for the input as well and still receive an error "command not found" when checking input vs randNum variable
n=$RANDOM$RANDOM$RANDOM; let "n %= 10000000000";
echo $n
for i in {5..1}; do echo $i; sleep 1; tput cuu1; tput el; done
tput cuu1; tput el
echo "what was that number?"
#read input
input=999999999
if [$input == $n]
then
echo "you are correct"
else
echo "you are incorrect"
fi
Shells need spaces around brackets [ and ] when used for this purpose (replacement syntax for the test command), and you should better use -eq instead of == for numeric comparison:
if [ $input -eq $n ]
If you use the arithmetic comparison, rather than the old testcommand (a.k.a. [) then you can avoid these issues. Spaces here are less important inside the brackets:
if (( input == n ))
Note that the leading $ is not required (and using it can cause issues)
This question already has answers here:
Sequences expansion and variable in bash [duplicate]
(7 answers)
Closed 7 years ago.
Im trying a code in bash to generate prime nos as follows:
#!/bin/bash
echo "Enter till where u wish to generate"
read num
echo "Generating prime numbers from 2 to $num"
flag="prime"
for i in {2..$num}
do
for j in {2..$((${num}-1))}
do
[ $((${i}%${j})) -eq 0 ] && flag="nprime" || flag="prime"
break
done
[ "$flag" == "prime" ] && echo "$i"
done
Upon execution, it throws an error because the for loop takes the sequence mentioned in the curly braces as it is not as a sequence.
Could you guide me as to where am i going wrong ?
man bash in my version says:
A sequence expression takes the form {x..y[..incr]}, where x and y are either integers or single characters, and incr, an optional increment, is an integer.
You can't use variables in ranges. Try seq instead:
for i in $(seq 2 $num) ; do
Note that incr for seq goes between x and y.
Use:
for ((i=2; i<=$num; i++))