bashmacoslaunchd

Bash script evaluates differently via term and MacOS launchd


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:

  1. Ensuring both were using /bin/bash (they were) and running as me.
  2. Sending the variable to stdout to confirm.
  3. Running them without the curl, just grepping a local file.

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?


Solution

  • 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").