I have a question about file test expressions in bash. Here is a simple script to illustrate my question:
set -x
read -p "Enter a filename: " var1
if [ - e $var1 ]
then
echo file exists
else
echo file not found
fi
There are three scenarios:
foo
, which is a file that exists in the directory from which I'm running the script. As expected, the output is file exists
.bar
. No such file exists in the directory from which I'm running the script. As expected, the output is file not found
.<enter>
without typing anything. Surprisingly, the output is file exists
.If I use if [[ -e $var1 ]]
, i.e., double brackets instead of single, the behavior is correct: even in the third case, I get file not found
.
I stuck a set -x
at the top of the file to see what was going on. With single brackets, the variable is evaluated as: '[' -e ']'
. With double, it is evaluated as [[ -e '' ]]
. This is interesting. Why is the expression being evaluated differently in the two cases?
I would be grateful for an explanation. Sorry if I'm missing the obvious. Thanks!
In this article, we discussed the differences between single and double brackets in Bash. The single bracket is a built-in command that's older than the double bracket. The double bracket is an enhanced version of the single bracket. If we want the portability of scripts, we should prefer single brackets.
Double brackets in bash are not a command but a part of the language syntax. This means they can react more tolerantly to 'disappearing' arguments: $ [[ $a = $b ]] || echo "unequal" unequal.
The double bracket is a “compound command” where as test and the single bracket are shell built-ins (and in actuality are the same command). Thus, the single bracket and double bracket execute different code. The test and single bracket are the most portable as they exist as separate and external commands.
Single and Double Brackets Bash provides the test command. This lets you test logical expressions. The expression will return an answer that indicates a true or false response. A true response is indicated by a return value of zero.
change to if [ -e "$var1" ]
You can find more details of []
and [[ ]]
Here
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With