I have a very simple bash script that curls a URL, counts a substring in the response, and runs some code if it finds the string.
Originally, I wrote it like this:
RESP=$(curl -s 'https://theurl.com' | grep -ic substring)
if [ $RESP > 0 ];
do something
else
do something else
fi
This worked great from my terminal prompt.
When I set it up to run in launchd as a local user launch agent, the if statement never evaluated to true.
Things I tried during debugging:
Eventually, I was able to get it to work by changing the if to:
if [ $RESP -ge 1 ]
That works in both places, but I can't figure out why the exact same script in the exact same interpreter would evaluate differently in both places.
Any ideas?
It's because the >
doesn't do what you think it does. The command
[ $RESP > 0 ]
is treated by the shell as a funny way of writing
[ $RESP ] > 0
That is, it runs the command [
(yes, that's an actual command, essentially equivalent to test
) with the expansion of $RESP
and "]
" as arguments. The fact that > 0
is in the middle of the arguments to [
doesn't matter; you can put a redirection operator anywhere in the command ... argument(s) sequence, and it does the same thing.
Net result: [
checks to see if $RESP
expands to a non-blank string (succeeding if it does), and sends its (empty) output to a file named "0".
At least, that's what it does normally. I suspect when you run it as launch agent, it's getting an error creating the "0" file, so it fails. And since it fails, and it's the condition of an if
statement, the else
clause runs.
To use >
or <
in a [ ]
test expression, you need to quote or escape it, like [ "$RESP" ">" 0 ]
or [ "$RESP" \> 0 ]
. Also, >
is the wrong test operator anyway; if you're comparing integers, use -gt
instead. In a [ ]
test expression, >
denotes sorting order comparsion (so [ 9 ">" 10 ]
is true, because "9" sorts after "1").