How can I do division with variables in a Linux shell?
Solution 1
Those variables are shell variables. To expand them as parameters to another program (ie expr
), you need to use the $
prefix:
expr $x / $y
The reason it complained is because it thought you were trying to operate on alphabetic characters (ie non-integer)
If you are using the Bash shell, you can achieve the same result using expression syntax:
echo $((x / y))
Or:
z=$((x / y))
echo $z
Solution 2
I believe it was already mentioned in other threads:
calc(){ awk "BEGIN { print "$*" }"; }
then you can simply type :
calc 7.5/3.2
2.34375
In your case it will be:
x=20; y=3;
calc $x/$y
or if you prefer, add this as a separate script and make it available in $PATH so you will always have it in your local shell:
#!/bin/bash
calc(){ awk "BEGIN { print $* }"; }
Solution 3
Why not use let; I find it much easier. Here's an example you may find useful:
start=`date +%s`
# ... do something that takes a while ...
sleep 71
end=`date +%s`
let deltatime=end-start
let hours=deltatime/3600
let minutes=(deltatime/60)%60
let seconds=deltatime%60
printf "Time spent: %d:%02d:%02d\n" $hours $minutes $seconds
Another simple example - calculate number of days since 1970:
let days=$(date +%s)/86400
Solution 4
Referencing Bash Variables Requires Parameter Expansion
The default shell on most Linux distributions is Bash. In Bash, variables must use a dollar sign prefix for parameter expansion. For example:
x=20
y=5
expr $x / $y
Of course, Bash also has arithmetic operators and a special arithmetic expansion syntax, so there's no need to invoke the expr binary as a separate process. You can let the shell do all the work like this:
x=20; y=5
echo $((x / y))
Solution 5
To get the numbers after decimal point, you can do this:-
read num1 num2
div=`echo $num1 / $num2 | bc -l`
echo $div
Related videos on Youtube
Judking
Updated on November 09, 2020Comments
-
Judking over 3 years
When I run commands in my shell as below, it returns an
expr: non-integer argument
error. Can someone please explain this to me?$ x=20 $ y=5 $ expr x / y expr: non-integer argument
-
Todd A. Jacobs almost 11 years@ShivanRaptor While one might argue that the question is an RTFM question, it is certainly a valid shell programming question. It is also a reasonable question for someone coming from languages that don't require dereferencing (e.g. Ruby or JavaScript). It should be left open.
-
Brian Campbell almost 11 years@ShivanRaptor No, this is on topic here. It's about programming in Bash. Unix/Linux is primarily for using the system, not programming. Now, shell scripting does span the boundary between programming and using the system, so this could be on topic on either site. If there were a question about "how do I set up networking", that would definitely belong on Unix/Linux. If it were a question about interactive keybindings in Bash, that would also belong there. But a question about shell scripting is definitely on topic here as well as there.
-
Victoria Stuart about 5 yearsSee my answer here, that illustrates subtraction and division of $BASH variables, using a call to Python from the shell (to convert int to float ...): stackoverflow.com/questions/8385627/…
-
-
paddy almost 11 yearsYou can find out a lot by reading through the man-page for bash. Type
man bash
at the prompt (q
to exit) -
Todd A. Jacobs almost 11 yearsSee Arithmetic Expansion and Shell Arithmetic in the Bash Reference Manual for all the gory details.
-
Gilles Quenot almost 11 yearsThis has nothing to do with dereferencing but interpolating and
expr
is discouraged in 2013. -
Todd A. Jacobs almost 11 years@sputnick You are clearly confused. Please feel free to consult a dictionary. See dereference and interpolate.
-
Prashant Kumar almost 11 yearsI've heard "interpolate" being used to refer to what others might call parameter expansion. At first, I was going to say, keep dereferencing talk to C and C++ code, but no, they say it in Bash world too. So we're all talking about the same thing. +1 for the vote against
expr
though. -
Gilles Quenot almost 11 yearsA better word is expanding, but not dereferencing. dereferencing is used when we use pointers, that's not the case here, that's just simple variables.
-
Gilles Quenot almost 11 years@Prashant: tldp is not known to be a good reference in the bash world.
-
Skippy le Grand Gourou over 9 yearsIt has to be noted somewhere on this page that most (if not all) GNU/Linux shells only perform integer operations.
-
Eugene over 6 yearsYou may also use
echo '1 / 3' | bc -l
-
dave_thompson_085 about 4 yearsThis is wrong.
/
works fine as a shell-case label. What doesn't work is to use*
for multiply without quoting it, which might be what you actually did; that causes it to effectively override all following items in the case, which in your example is 'devide' and 'modulo'