Comparisons in Shell [duplicate] - bash

This question already has answers here:
Why should there be spaces around '[' and ']' in Bash?
(5 answers)
Closed 4 years ago.
I am trying to write a program that checks whether the number stored in a file (variable n) + 8 is greater or equal to 100. If it is, terminate, else, add 8 and store back in file. However, when I try running it, it says the command in line 4 (if condition) cannot be found. Can someone please explain to me why this isn't working? Thanks.
#!/bin/bash
n=$(cat test.txt)
if [$(($n+8)) -ge 100]
then
echo 'terminated program' > test.txt
else
m=$(($n+3))
echo $m > test.txt
fi

You miss some spaces :
if [$(($n+8)) -ge 100]
->
if [ $(($n+8)) -ge 100 ]
But while using bash, prefer a modern solution, using bash arithmetic :
if (( n+8 >= 100 ))
or even
if ((n+8>=100))
Like #Gordon Davisson said in comments : arithmetic contexts like inside (( )) are one of the few places in bash where spaces aren't critical delimiters.

Related

Unix script error while assigning command substitution to array variable [duplicate]

This question already has answers here:
Why does my Bash code fail when I run it with 'sh'?
(2 answers)
Closed 2 years ago.
From the below script I am assigning the command substitution for the array variables.
When I execute the script, the script is throwing error as
myscript.sh: 22: scr4.sh: Syntax error: "(" unexpected
ie while executing the command suite=( echo $Suites ).
I took this script from Advanced Bash scripting Guide pdf.
When I run this command by command in CLI, there is no issue.
What is the solution for this?
#!/bin/bash
Suites="Clubs
Diamonds
Hearts
Spades"
Denominations="2
3
4
5
6
7
8
9
10
Jack
Queen
King
Ace"
suite=( `echo $Suites` )
denomination=( `echo $Denominations` )
num_suites=${#suite[*]}
num_denominations=${#denomination[*]}
echo -n "${denomination[$((RANDOM%num_denominations))]} of "
echo ${suite[$((RANDOM%num_suites))]}
exit 0
You're probably using the wrong interpreter.
$ bash cards.sh
King of Diamonds
$ sh cards.sh
cards.sh: 22: Syntax error: "(" unexpected
POSIX shell does not support arrays. You define an array on line 22 (suite=( `echo $Suites` )) and another on the next code line, then most of your remaining lines refer to those arrays. $RANDOM is also unavailable in POSIX.
Another note, you don't need those subshells. Here's a cleaned up version of your code:
#!/bin/bash
suit=( Clubs Diamonds Hearts Spades )
denomination=( {2..10} Jack Queen King Ace )
echo -n "${denomination[ $(( RANDOM % ${#denomination[#]} )) ]} of "
echo "${suit[ $(( RANDOM % ${#suit[#]} )) ]}"
exit 0
This doesn't launch any subshells. Instead, it's directly defining the arrays. I used {2..10} (another bashism) as shorthand for listing each number. Rather than storing the lengths in variables, I'm invoking them directly in the modulo math, which I've spaced out to make more legible.
I changed ${variable[*]} to ${variable[#]} as well. This doesn't matter in your particular code, but it's generally better to use # since it is better at preserving spacing.
I also corrected the spelling of your suite variable to suit. Feel free to revert if that's actually what you desired (perhaps due to a spoken language difference). It of course doesn't really matter as long as you're consistent; bash doesn't know English 😉

Bash float comparison error with different number of digits [duplicate]

This question already has answers here:
How can I compare two floating point numbers in Bash?
(22 answers)
Closed 4 years ago.
Ok, so I've been working around with some results from speedtest-cli and realised that I had some errors due to the fact that bash doesn't seem to correctly handle the change in digits?
Anyways, here is an example ran directly from the terminal :
ubuntu:~$ l1=9.99
ubuntu:~$ l2=10.44
ubuntu:~$ if [[ (($l2 > $l1)) ]]; then echo "Ok"; fi
ubuntu:~$ if [[ (($l2 < $l1)) ]]; then echo "Not ok"; fi
Not ok
Of course, comparing eg. 10.33 and 11.34 would give the right result.
How does this happen and how can I fix it? Is there another way to achieve this comparison?
Thanks
You're using string comparison, not numeric. Inside double square brackets, parentheses are used just for precedence, so your condition is equivalent to
[[ $l2 < $l1 ]]
To use numeric comparison, use double parentheses without the square ones:
(( l2 < l1 ))
Unfortunately, this wouldn't work either, as bash doesn't support floating point arithmetic, only integer.
You need to use an external tool, e.g.
bc <<< "$l1 < $l2"
bc returns 1 for true and 0 for false.

Verify amount in bash [duplicate]

This question already has answers here:
How can I compare two floating point numbers in Bash?
(22 answers)
Closed 5 years ago.
Currently i'm writing a script that checks whether an amount is higher than the other.
if [ "324,53" -gt "325,00" ]; then
echo "Amount is higher!"
else
echo "Amount is lower."
fi
Obviously i'm receiving the error: "integer expression expected" when running this. I tried to use sed 's/[^0-9]*//g'` but i need the full number again for further use. Problem is that I don't know the correct way how to do this. Can anybody give some advice?
Bash can't handle floating point numbers. You need to use an external tool, e.g. bc, but you need to use decimal point, not comma:
if (( $(bc <<< '324.53 > 325.00') )) ; then
bc prints 1 when the condition is true, and 0 when it's false. $(...) takes the output of the command, and (( ... )) interpret it as a number, returning false for zero and true for anything else.

How to evaluate mathematics in Ubuntu console? [duplicate]

This question already has answers here:
Bash: evaluate a mathematical term?
(9 answers)
Closed 6 years ago.
When I try to calculate a maths problem such as 1 + 1 using the Ubuntu console like this:
user#servername:~$ 1 + 1
Ubuntu thinks the first 1 is a command and I get this error:
1: command not found
I then tried to use echo to evaluate the string (with and without quotes) like this:
user#servername:~$ echo 1 + 1
user#servername:~$ echo "1 + 1"
Unfortunatly both output 1 + 1 and not 2.
It would also be greatly appreciated to include a explanation as to why echo does not evaluate the specified string before outputting it?
Also is there is a built-in command that evaluates a string before outputting it (maybe something that behaves like eval in Python)?
Thank you for the help in advance.
The one I usually use is
bc<<<2+2
You can make that easier to type with an alias:
$ alias x='bc<<<'
$ x 53*(27-23)
212
If you put whitespace in the expression you'll need to quote it. Also if the expression starts with an open parenthesis (as opposed to having one in the middle).
$ echo $((1+1))
2
$ echo "1+1" | bc
2
$ awk 'BEGIN{print 1+1}'
2

binary execution in a while loop.for loop through shell script

Hello i am new to shell script. want to execute a binary through loop in a shell script.
wrote a pgm which looked like:
i="1"
while [ $i -lt 100 ]
do
/home/rajni/BUFFER_SEND_STUB/build/buffer_send.exe
i=`expr $i +1`
done
doubt it is not working fine. Can anyone suggest????
Thanks.
expr won't like the fact you've used +1 rather than the space-separated + 1.
I also tend to use [[ and ]] rather than the single ones since they're definitely bash-internal and more powerful than the external [/test.
In any case, there's a more efficient way if you're using a relatively recent bash:
for i in {1..100} ; do
echo $i
done
which will do something with each value 1 through 100 inclusive (your current loop does 1 through 99 so you may have to adjust for that).
Changing that 100 to a 5 shows how it works, generating:
1
2
3
4
5
you can use the for loop
for i in {1..100}
do
/home/rajni/BUFFER_SEND_STUB/build/buffer_send.exe
done

Resources