Reputation: 135
This following script will creates a file named "Happy", i couldn't figure out why, can someone try this script and tell me what is happening? Thanks!
#!/bin/bash
str1=""
str2="Sad"
str3="Happy"
if [ "$str2">"$str3" ]
then echo "$str2 is greater than $str3"
elif [ "$str2"<"$str3" ]
then echo "$str2 is less than $str3"
fi
Upvotes: 2
Views: 131
Reputation: 3832
If you rewrite the code as follows:
#!/bin/bash
str1=""
str2="Sad"
str3="Happy"
if [[ "$str2" > "$str3" ]]
then echo "$str2 is greater than $str3"
elif [[ "$str2" < "$str3" ]]
then echo "$str2 is less than $str3"
fi
then the comparisons should occur correctly and you can avoid inadvertent file creation. The extra pair of "[" and "]" takes the code out of test context, allowing for comparison and avoids file creation. More info here which states the following:
Note that the ">" needs to be escaped within a [ ] construct. ... Note that the "<" needs to be escaped within a [ ] construct.
The reason is that in a test context, i.e. using only a single pair of square brackets as in the OP code, ">" and "<" are interpreted as redirection operators. So, instead of meaning greater than and less than respectively, ">" means direct the output of a command to a file whereas "<" means give input to a command.
Upvotes: 2
Reputation: 531215
[
is just a (silly) alias for the test
command; everything following it (including the mandatory closing ]
) is an argument. (What you have is treated the same as if test "$str2">"$str3"
.)
There are two issues:
The operands and the operators need to be separated by whitespace.
# still not quite right, but ...
if [ "$str2" > "$str3" ]
Since >
and <
are interpreted as redirection operators by the shell, they have to be escaped so that they are passed as arguments to [
.
if [ "$str2 \> "$str3" ]
(You might think just escaping the operator would be sufficient; however, "$str2"\>"$str3"
would be treated as a single string argument to test
rather than three separate arguments which test
will interpret as an expression. test "$str2"\>"$str3"
would simply check if the single argument is empty or not.)
Since you are using bash
, it's far simpler to just use [[
instead of [
. [[
is not a regular command; it's special syntax recognized by bash
, so that normal processing rules don't apply. Most relevant here is that >
is a string comparison operator, not a redirection operator, so it doesn't need to be escaped.
if [[ $str2 > $str3 ]]
Upvotes: 3