Case Study - Bash Arithmetic Expression
intro
eval
is considered bad in many languages, including bash. In this case study, we’ll talk about an alternative to eval
, but still quite effective.
case study
In bash scripting, we can use []
as an equivalent to test
. In some implementations, you may see people using [[]]
instead, and it’s considered a much more reliable version of test
. Inside the test, the expression will be evaluated and very often we have [[ expr -eq "123" ]]
.
In the above expression, the part expr
and "123"
will be interpreted in the arithmetic context hence evaluated. Let’s see an example script:
test='1+3'
if [[ "$test" -eq "5" ]]; then
echo "1"
else
echo $test
fi
if [[ "$test" -eq "4" ]]; then
echo "2"
else
echo $test
fi
The output from the script will be like this
# bash test.sh
1+3
2
This means, the variable test='1+3'
has been evaluated arithmetically. And if we were to exploit this characteristic, we could do things like the following
$((expr))
((expr))
${var:expr:expr}
${var[expr]}
var[expr]
Let’s try modify the script and see the effect
test='a[$(date >&2)]+1'
if [[ "$test" -eq "1" ]]; then
echo "1"
else
echo $test
fi
This will output the following, which means, the expression $(date >&2)
has been executed.
# bash test.sh
Thu Feb 23 08:03:55 PM EST 2023
1
how to prevent this?
Basically nothing really effective. One could attempt to do better input validation on user supplied inputs. But in the end, bash is not a programming language.