Running shell commands in macro

Sorry if this is a stupid question, but can I run shell commands in macros? I see I can run shell scripts, and I can certainly wrap a command in a shell script, but I'd like to avoid having to do that if I can just run commands.

Thanks.

Try it. You’ll get an answer you’ll trust more than anything we could tell you.

2 Likes

I have and it didn't work, but I figured there might be an action I wasn't seeing that deals with this.

Starting simple:

Plenty of info on the Wiki page (where the first shows the utility tr being run) but there's also gotchas in terms of environment, returning results, etc.

If you're trying something and it doesn't work, post it so people can see what you are trying to do -- saves a whole lot of guesswork.

What are you trying to do?

The Execute a Shell Script action executes a shell, which can run whatever commands you want. Or you can start your script with #! and specify a different interpreter, such as perl or python.

I'm trying to use some of these commands in KM macros.

I suspect your command failed because the environment in which Execute Shell Script runs is not the same as the environment you’re used to in Terminal. As @Nige_S and @peternlewis suggest, show us what you’re trying to do, and maybe we can figure out what’s going wrong.

1 Like

Thanks. This started for how I listen to music at work on my Mac. My music library is on my iPhone, so I always plugged the iPhone into the Mac and accessed the music via iTunes. This allows me to use the KM music controls to play, pause, skip, etc., and use the headphone plugged into the Mac that I use for other things as well. In the Music app that replaced iTunes, I can access the music like in iTunes, but it doesn't have the column browser for it like iTunes did. It may sound silly, but this is the only way I like to see my music library. So the only way I could do that that I could think of is installing iTunes via Retroactive. But controlling it via KM never really worked until I discovered this m-cli. I was pleasantly surprised to find that its 'itunes' command actually controls the Retroactive-installed iTunes, not Music. This solved my issue. What I'm trying to do in the KM macros for play/pause, skip, etc., is running those commands, like 'm itunes play'. I have it working right now by wrapping those 'm' commands in shell scripts, but it would be simpler to run those commands directly from the KM macros.

Does that all make sense?

Almost. Even better would be if you posted the macro, or even just the problematic action, along with the error (if any) you are seeing.

BTW, "Execute a Shell Script" suppresses errors and trims results by default -- you'll get more feedback for debugging if you "display results in a window" then disable "Trim Results" and enable "Include Errors". Both those options are in the action's "gear" menu.

BTW2, have you tried using AppleScript rather than command line utilities? iTunes has a rich AppleScript dictionary...

Edit to add: In fact the iTunes part of m-cli is all AppleScript via osascript, so it should be easy to do whatever you are doing directly with "Execute an AppleScript" actions. Still worth getting your head around how the Script action handles ENV etc, for future use.

1 Like

At the risk of understatement, questions including the word shell are exceedingly common on this forum,

and almost always have the same resolution:

You need to specify the full path to a command (in a vanilla shell instance no search paths are defined by default, and the Terminal.app paths are not inherited by Execute Shell Script actions).


I wonder whether the Discourse software can be configured to explain this briefly (and point to other posts) before a user loses time by starting a new thread with shell in the title ?


See: action:Execute a Shell Script [Keyboard Maestro Wiki]

This is the macro. Each shell script is simply running the command. For example, itunes-play.sh is:

#!/bin/sh
/usr/local/bin/m itunes play

But, you do raise a point that if the execution would be cleaner as a shell script here, it's probably worth leaving as I have it here.

image

I think you misread my post. The shell scripts work fine. I was just trying to run the actual commands inside them from the macro, if possible.

1 Like

This is pretty inefficient -- you're spawning a shell to read a file that spawns an AppleScript process to find out out if iTunes is currently playing, then spawning another shell to read a file that spawns an AppleScript process to play or pause iTunes. All you actually need is the following KM macro (set your trigger to suit):

iTunes Play or Pause.kmmacros (1.5 KB)

I realise you're only giving an example, but the above might be enough to convince you that m-cli is possibly not your best solution :wink:

However, that still leaves us with why your macro isn't working, and solving that might help you in the future. I'd start by changing the actions to something like this:

Turning off "Trim Results", turning on "Include Errors", and turning off "Failure Aborts Macro" should get you a more informative error message in a KM "Display Text" window, which will (hopefully!) give us some clues.

1 Like

Well holy crap. That is simple, elegant, and quick. Perfect. Thank you! I never claimed to be efficient with this stuff and don't have any experience with AppleScript. Thanks so much!

Forgive the tangent: why would turning off Trim Results give you more info? Doesn’t it just delete leading and trailing whitespace?

There was a thread a few weeks back where the actual problem was hidden by "Trim Results" -- IIRC the shell script was erroneously returning just a newline, that was trimmed out, so KM didn't pop a "display results window" and it looked like the script was silently failing.

And I guess I'm a fan of getting all the things when troubleshooting!

1 Like