Reputation: 82
I have test.sh as shown below. When I run it like ./test.sh from bash shell, I get output as shown below.
test.sh
operator="\*"
echo $operator
expr 5 $operator 1
expr 5 \* 2
output
\*
expr: syntax error
10
I am not understanding why does it give syntax error for the third statement while fourth statement is working as expected. If expr is only getting * as second argument in third statement, how does echo output \*?
Upvotes: 1
Views: 97
Reputation: 4896
The final stage of shell expansions in bash is quote removal:
After the preceding expansions, all unquoted occurrences of the characters ‘
\
’, ‘'
’, and ‘"
’ that did not result from one of the above expansions are removed.
The "above expansions" here being parameter (variable) expansion, command substitution, etc.
In expr 5 \* 2
, the \
will be removed by bash as part of quote removal, since it is not a result of variable (or other) expansions. So here, the argument that expr
gets is *
, after the removal of \
.
In expr 5 $operator 1
and echo $operator
, the \
will not be removed, since it's a result of variable expansion. So in both of these commands, the argument that echo
and expr
get is \*
, without the \
being removed.
The best way here is to use quotes consistently:
operator="*"
echo "$operator"
expr 5 "$operator" 2
Otherwise, \*
might still be subject to field splitting, if IFS
happened to be set to something weird:
bash-4.4$ foo='\*'
bash-4.4$ echo $foo
\*
bash-4.4$ IFS='*'
bash-4.4$ echo $foo
\
bash-4.4$ echo "$foo"
\*
Upvotes: 1