`Execute Shell Script` failed with status 1 even though I've already exported PATH

Hello folks,

I'm here with another noob question that I wasn't able to find an answer for in the forum. Thank you so much for your kind help <3

What I'm trying to do

In this Execute Shell Script Action, I'm using ack, a grep-like tool, to find a RegEx pattern in a local file:

(The DUSK part will be replaced by a $KMVAR when actually using the macro, but I'm using the text DUSK instead of a variable to make debugging easier.)

What went wrong

ack -o '[0-9]{6}(?=,"name":"DUSK")' ~/Documents/Misc/Steam.json
       |_____RegEx pattern________| |_______local file________|

When I run the above command in Terminal.app, ack correctly returns a match as I expected. But when I run either one of these two below in the Execute Shell Script Action:

#!/bin/zsh
/usr/local/bin/ack -o '[0-9]{6}(?=,"name":"DUSK")' ~/Documents/Misc/Steam.json
#!/bin/zsh
export PATH=/usr/local/bin:$PATH;
ack -o '[0-9]{6}(?=,"name":"DUSK")' ~/Documents/Misc/Steam.json

Keyboard Maestro simply reports the following in Engine.log, which I find too vague to be helpful:

Action 15037406 failed: Task failed with status 1
Task failed with status 1. Macro “Trying” cancelled (while executing Execute Shell Script).

How I tried (and failed) to fix it

I tried running this in the Execue Shell Script Action instead:

#!/bin/zsh
export PATH=/usr/local/bin:$PATH;
which ack
# ack -o '[0-9]{6}(?=,"name":"DUSK")' ~/Documents/Misc/Steam.json

and when then Action displays the results in a window afterward, the results are, as expected,

/usr/local/bin/ack

which, I believe, means KM's shell is indeed aware of what ack is after I've exported the PATH. So I've really no idea what's going on here or what to do next.

Questions

I assume I can always avoid these issues by configuring the Action to Execute script file instead of Execute text script, but I'd really like to obtain a deeper understanding of what I'm doing wrong in the above. Learning is fun! :smiley:

Thank you again for all your patience and time!

Ensure the Include Errors is turned on in the action gear menu, and check the Engine.log file for the full error message.

There is nothing obviously wrong, but the task is returning status code 1, so it's complaining about something. It could be related to some other environment variable, or perhaps there is some sort of security or permission issue involved.

1 Like

Thank you for your reply Peter!

After reading you reply, I changed the "Include Errors" setting for this Action from the default "off" to "on", but Engine.log still didn't provide a full message. I tried both the "Try Action" option in the Execute Shell Script Action's contextual menu:

Action 15038174 failed: Task failed with status 1
Task failed with status 1. Macro “Trying” cancelled (while executing Execute Shell Script).

…as well as running the entire macro, since I'm unsure if these two might produce different results:

Execute macro “Routine - Trello media inbox” from trigger Editor
Action 15038174 failed: Task failed with status 1
Task failed with status 1. Macro “Routine - Trello media inbox” cancelled (while executing Execute Shell Script).

These five lines of log were all that appeared, nothing more detailed.

Quick question: the status code 1 is returned by Keyboard Maestro Engine, not whatever binary the user is running (in my case, ack) in KM's shell, right?

Either way, since you said there is nothing obviously wrong, I'll just try to find another way for it to work instead of trying to get to the bottom of the error. :smiley:


Edit:

perhaps there is some sort of security or permission issue involved

KM and KM engine both have full disk access enabled, and I have another perfectly functional macro whose trigger is newly added files in ~/Documents/LilyPond. Not sure if this is necessary, but I just wanted to clarify for potential readers that my installation of KM does have access to the necessary folders.

No, the status code of 1 is being returned as an error from the ack tool.

OK, I checked a man page for ack at:

And a couple things stood out:

  • There is a reference to the .ackrc and that might be relevant.
  • There is a large section on Environment Variables and if any of them are defined then that could be relevant.

But then I got down to Shell and Return Code and it says:

For greater compatibility with grep , ack in normal use returns shell return or exit code of 0 only if something is found and 1 if no match is found.

So that would seem to be the issue - that it is working fine but finding nothing.

This also explains why it's not reporting anything to stderr, because despite returning a non-zero error status, there is no actual problem to report.

So unless it actually is an error to not find any matches, you basically have to ignore the error. You could either just turn off reporting the error or failing the macro in the gear menu, or you could remove the status code from the return, perhaps with something like:

ack …  || echo "Nothing found"
1 Like

Thank you again for your follow-up reply, Peter!

That's surprising to hear for me, because as I described in the main post, running the same command in Terminal.app does in fact return a match, which is why I assumed earlier (after checking ack's manual) that the status code 1 was not returned by ack, but by Keyboard Maestro Engine instead.

I also tried yesterday to use GNU grep and ran into (ostensibly) the same issue: the command returns a match as expected when run in Terminal.app (ggrep …), but status code 1 when run in Execute Shell Script (/usr/local/bin/ggrep …). Still no idea what I'm doing wrong.

I only just learned the trick during the last few days—seems very useful indeed, I'm sure it'll come in handy! some day!

In that case, I would try and simplify it all down to the minimum to get a match, with commands like the following.

Ensure the file can be read, and contains what you expect:

#!/bin/zsh
cat ~/Documents/Misc/Steam.json

Ensure a trivial pattern matches:

#!/bin/zsh
ack -o 'DUSK' ~/Documents/Misc/Steam.json

Ensure a simple pattern matches:

#!/bin/zsh
ack -o '[0-9]{6}' ~/Documents/Misc/Steam.json

Basically, narrow down what part of the script is the problem.

1 Like

Okay this is amazing and weird. During the ~4h after my last reply, I modified the macro so that it now no longer uses Execute Shell Script to do Regular Expression matches at all. As a result, after reading your latest reply just now, I had to use Keyboard Maestro's "File > Revert Macros" command. I ran the macro in question after reverting and surprisingly, this time Execute Shell Script did return the correct match.

More details about the reversion, most likely irrelevant:

Details

When I ran "File > Revert Macros", I chose the newest "backup", which is dated from yesterday. But I've been modifying and debugging so many times for the last few days and the macro didn't work as I intended for a single time, so regardless of which exact timestamp from yesterday Keyboard Maestro reverted me to, it should have contained a non-functional version of this macro.

After the reversion, I copied the macro, ran "File > Revert Macros > Before Last Revert", pasted it, enabled it because I did disable it yesterday, and changed its name to avoid potential confusion. I did not change a single thing about the Actions in the macro.


Anyway, the insightful tips about starting simple and gradually increasing complexity is definitely a great approach to debugging, I will keep them in mind! :smiley:

1 Like

I very much doubt restoring the macro was the difference.

If I had to guess, I'd say an issue with reading the file, or the contents of the file.

Anyway, you have lots of tools to use if you have an issue again.

1 Like

Indeed! My debugging skills certainly improved a lot. Thank you again for the many patient and helpful replies, Peter!

1 Like