Those escaped quotes in \"test\"
make me think that there's some confusion about the quoting rules of shell, because the first piece of code works as intended and $STATUS == \"test\"
shouldn't (unless you wrote STATUS=`echo '"test"'`
or something similar).
To properly clarify this confusion, it is needed to explain some shell concepts.
Quoting
In POSIX shells, quoting is one of the most important mechanisms. Unfortunately, it is also a very confusing topic and, when used incorrectly, a big source of bugs and weird behavior in scripts.
The basic rules are the following:
- Escape character
\
: Preserves the literal value of the next character that follows, with the exception of <newline>
.
- Double quotes
"
: Preserves the literal value of all characters within the quotes, with the exception of $
, `
, \
and, when history expansion is enabled, !
.
- Single quotes
'
: Preserves the literal value of all characters within the quotes, without exceptions.
Command substitution
Command substitution allows the output of a command to replace the command itself. Its syntax is either $(command)
or `command`
, although the former is prefered.
Test command
The test
command (also known as [
in POSIX and [[
in shells like bash, ksh and zsh) let you use many useful conditional and arithmetical expressions. For example, it can check if a given regular file exists and is readable, if two strings are equal or if a number is greater than another.
Now, analyzing the code:
STATUS=`echo "test"`
The command substitution here is useless, as it could have been written as STATUS="test"
. Note that the double quotes are not printed by echo
, so STATUS
holds test
as its value.
if [ $STATUS == "test" ]; then
exit 0
fi
Here are, at least, 3 potential flaws:
- The unquoted
$STATUS
could be affected by word splitting.
==
is non-POSIX syntax. Use =
if you care about portability.
if
and exit 0
are useless in this scenario as [
already does the intended job.
Also, note that, as the previous line of code, the double quotes are not taken literally, so the resulting command (after expansion and quote removal) is [ test = test ]
, which is true.
But if your goal was to have "test"
as the value of STATUS
, then
STATUS=\"test\"
STATUS="\"test\""
STATUS='"test"'
are all valid assignments and
[ "$STATUS" = \"test\" ]
[ "$STATUS" = "\"test\"" ]
[ "$STATUS" = '"test"' ]
are all valid conditional expressions.
set -x
before this to see what's happening in your situation. BTW,if [ "$STATUS" = "test" ]; then
(with double-quotes around the variable and a single=
sign) is the preferred form. Also, I recommend avoiding all-caps variable names (likeSTATUS
) -- there are a bunch of all-caps vars with special meaning, and it's easy to re-use one of those and get weird results. Lower- and mixed-case variable names are safer. – Gordon Davisson Jun 29 '18 at 05:29if
statement, addecho "STATUS=<$STATUS>"
. Whatever is reported inside the angle brackets is the value you need to test. – Chris Davies Jun 29 '18 at 07:00STATUS=`echo '"test"'`
, ieSTATUS='"test"'
. – Chris Davies Jun 29 '18 at 07:02