I was creating a program that calculates the area of circle, but bash doesnt compile and execute due to error message in the title. Here is my code:
elif [ $num -le 6 ] && [ $num -ge 4 ]
then
read -p "Enter radius: " radius
let areaCirc=("scale=2;3.1416 * ($radius * $radius)"|bc)
echo "Area of the circle is: " $areaCirc
and the error message is: syntax error near unexpected token '|'
can someone help me?
CodePudding user response:
- To send a string to a command via stdin, use a here-string
command <<< string
, not a pipe. - Command substitution syntax is
$(...)
, not(...)
. - Don't use
let
here. Shell arithmetic only supports integers.
areaCirc=$(bc <<< "scale=2;3.1416 * ($radius * $radius)")
CodePudding user response:
let
provides arithmetic context, but we have an ambiguity here, because in a let expression, the vertical bar (|
) means bitwise or, but in the shell it has also the meaning of a pipe operator. Look at the following examples:
let bc=4
let a=(4 bc) # Sets a to 8
let b=("5 bc") # Sets b to 9
let c=("(2 4)|bc")
This is syntactically correct and sets c to 6 (because 2 4 equals 6, and the bitwise or of 6 and 4 equals 6).
However if we decided to quote only part of the argument, i.e.
let c=("(2 4)"|bc)
or don't quote at all, i.e.
let c=((2 4)|bc)
we get a syntax error. The reason is that the shell, when parsing a command, first separates it into the different commands, which then are strung together. The pipe is such an operator, and the shell thinks that you want to do a let areaCirc=("scale=2;3.1416 * ($radius * $radius)"
and pipe the result into bc
. As you can see, the let
statement is uncomplete; hence the syntax error.
Aside from this, even if you would fix it, your using of let
would not work, because you are using a fractional number (3.1416
), and let
can do only integer arithmetic. As a workaround, either you do the whole calculation using bc
, or some other language (awk
, perl
,...), or, if this is an option, you switch from bash to zsh, where you can do floating point arithmetic in the shell.