I have an Execute Shell Script action that sets a local variable. If the commands in the script return nothing (an empty string), then the action errors out. For example: this works (the 'ps' command returns text that contains the string "root"):
ps -cA -o user,pid,command | grep "root"
but this version causes an error ("garbage" is not found in the 'ps' result):
ps -cA -o user,pid,command | grep "garbage"
An empty (null) string should be as valid as any other string. If I add an 'echo x' before the 'ps', the action still errors out. Why does a null string result cause an error?
That was a great answer and I discovered this exact problem myself independently and diganosed correctly myself. However I don't want this to end here. There's more clarification to be requested on this topic. Namely, why does KM generate error messages when the shell does not? For example, in a shell this does not generate an error:
echo q | grep z
But in a KM macro, it generates an error. I realize (now, after 8 hours of troubleshooting) what's happening, but why does KM make an "error" about something that the shell does not? Why is the behaviour inconsistent with the shell? I probably spent an entire day figuring this problem out for myself. I wouldn't have had to spend any of that time if the KM Execute Shell script action behaved exactly as the macOS shells do, which is to ignore this error. How is it even an error? In the man pages for grep it says that the command returns a 1 if there are no results. The shell doesn't report this as an error, so why does KM? This is inconsistent. I don't know who is right, but it's inconsistent.
I don't know how my tone of voice sounds, but I'm just trying to make a strong case, not sound unpleasant.
I'm here to petition that either (a) KM should interpret the results the same way that the shell does, and should not report an error or (b) if these behaviours are not aligned, then the KM documentation for the Execute Shell Script action should explicitly state that it behaves differently from the shell by returning any value>0 as an error, which the shell does not do. I see no mention in this following documentation about which return values generate errors or how KM differs from the shell in the way it reports them. Why can't the documentation mention this divergent behaviour? It should be mentioned at the top of the page under the heading "Important."
I think your beef is with grep, rather than Keyboard Maestro.
On my Mac, man grep lists the exit codes as:
EXIT STATUS
The grep utility exits with one of the following values:
0 One or more lines were selected.
1 No lines were selected.
>1 An error occurred.
This contradicts the Unix convention of using zero for normal exit and non-zero for abnormal.
For its own purposes, grep doesn't consider it an error to have no matches, which is why it doesn't emit a message. It is trying to signal to a calling program, through its exit code, that it ran successfully, but found no matches.
It's reasonable for a generic tool running on a POSIX platform (KM) to assume applications will follow the conventions of the platform. Grep isn't doing that, which is why you're seeing the behavior you're seeing. (If you happen to have your shell configured to highlight failed commands (e.g. with Starship), it probably will in fact treat a no-match grep as "failed.")
If you want to make a macro that acts differently based on grep's exit code, you could use the technique described here.
Both the shell and Keyboard Maestro report it as an error - just they report it in different ways. The shell reports it with $? and Keyboard Maestro reports it with the %ActionResult% token.
And the sequence of commands would stop if you had a sequence of commands; for example:
(echo q | grep z) && echo hello
which is essentially what a Keyboard Maestro action sequence is, assuming you have configured the Abort Macro on Failure checkbox (which is on by default).
If you don't want to hear about the error, adjust the gear menu options to not abort and not notify.