How to use where command in execute shell script action

Hi. The story is that i want to make a subroutine to make KM know where is FFmpeg by itself.
So I make this.


But what is interested is that KM says cannot find the command Where.
But I can use where in my terminal as normal.
So I run this
where where
in my terminal to see where is where. then i can tell KM where is it.
But terminal says
"
where: shell built-in command
"
I dont know how to do next.
If it's shell builtin command, why i cannot use it in execute shell action directly.

Read the "Execute a Shell Script" Wiki page, then bookmark it so you can go back again (and again). It's quite complicated how everything ties together, so don't worry if you don't get it all first time round.

But in this case...

Yes, where is a shell built-in -- but it is a built-in for the zsh shell. KM's "Execute a Shell Script" action defaults to using sh, where that command doesn't exist. You can either use the which command, present in sh, bash, zsh, etc:

which ffmpeg

...or if you must use zsh and where, tell the action to use zsh:

#!/bin/zsh
where ffmpeg

But -- and it's a big but -- both where and which use the current shell's environment variable $PATH and search each entry of that in turn to find the thing you are looking for. If ffmpeg isn't under one of those listed paths the command won't find it -- if it is in one of those paths, you don't need to use the whole path in your command because the shell will find ffmpeg without it!

So have a very careful read of the "Path in Shell Scripts" section. This is where all your problems are stemming from, and this is where you'll find the proper way of fixing them.

1 Like

first time to know I can do this
#!/bin/zsh
But with no luck, both
which ffmpeg
and

#!/bin/zsh
where ffmpeg

all failed on my machine.


I guess the problem is about apple silicon.
Really not happy :sweat_smile: :joy:
My macro is
_ge VIDEO Where is FFmpeg v0.kmmacros (6.2 KB)

No -- the problem is that you still haven't fully understood how the PATH environment variable works, how it is different in a Terminal shell and KM's "Execute a Shell Script" action, and how you can fix it.

Read "Path in Shell Scripts" again. Then go to Terminal and type:

echo $PATH

Then compare what you see there to the text displayed by the same in a shell script action, even when using zsh:

image

Exactly how you fix it will depend on how you installed ffmpeg, but the differences in the two outputs should give you a clue.

I'm afraid that if you are going to use command line utilities, sooner or later you're going to have to go into the weeds of how Unix works.

Please read @Nige_S' reply carefully: This is not about Apple Silicon. This is about the path that's available in shell script actions, as @Nige_S described:

From that page, here's the relevant bit:

Unless your ffmpeg lives in one of those directories—which is impossible, for the most part—then Keyboard Maestro's shell script action won't find it. You'll either have to specify the full path to the tool, or import the $PATH you want to use each time you use the shell script action. The linked page explains it all.

-rob.

I see.
I mixed up two different questions.


I run this, the output is correct. that means
#!/bin/zsh
make where command works in execute shell action.
then i run

#!/bin/zsh
where ffmpeg

failed. that's because PATH issue.
So my plan is failed. I want to make km know where is ffmpeg then set PATH by itself.
But actually the command - where - also need to be set PATH. Who set path for where?

For now I still need to set PATH manually for ffmpeg.
I will keep thinking.

Please -- just upload the outputs from both Terminal's echo $PATH and a shell script action's

#!/bin/zsh
echo $PATH

...so we can compare them. The answer is most likely in there (although some ffmpeg installs also set aliases in shell "startup" files, which is why I'm asking how you installed it).

If it is just a PATH issue you can make a single change to a single KM variable and solve your problem.

I had to do something similar for a macro that uses ImageMagick (the 'convert' utility, in particular). Almost everyone installing ImageMagick does so via either Homebrew or MacPorts, so I wrote this routine to check if either/both of those exist, and to use one if found:

Group.kmactions (5.4 KB)

A long screenshot hides here

Because 'ls' works with the default path, I try to list the contents of the path where convert should be when it's installed with either of those tools. I save the result to a variable, and then check if that variable contains "not found."

It's not perfect, in that it can't find versions installed via either methods, but it worked well for my needs. Maybe you could do something similar with ffmpeg.

-rob.

1 Like

i know where is ffmpeg on my machine.
but what I am doing here is:
I want to make a ffmpeg-kmmacro.
Anybody can run this on their machine. no need to think about PATH issue.
anyone of you could do this?:blush:
I want to make km find where ffmpeg is all by itself.

I ll check this.
many thanks.
but you still need to know opt/ this kind of apple shit😂 in your macro.
I just don't want to do this.
when you do condition check, you need to know possible conditions, that's what i want to get avoid.

Given Keyboard Maestro only runs on a Mac, I'm not adverse to have that stuff fin my macros. For ones I want to distribute, it offers the most flexibility for users of the macro, and the least amount of work.

Then you'll have to import your path, as described on the linked page. Do that, and then you can just call ffmpeg without a path.

-rob.

It's not Apple shit, it's Unix shit. And if you are going to use, or write macros for, Unix utilities that are installed outside of /usr/bin, /bin, /usr/sbin, or /sbin you had better get used to it.

The easiest method (for you, anyway) is to check if the user has been smart enough to update KM's ENV_PATH variable to suit however they've installed ffmpeg:

image

You can also do as @griffman shows above, although that only covers a couple of cases.

If you have time to spare you could try and find it and get the path from the result:

image

...though it would better to do that only once -- store the result in a global variable and only do the find if the variable does not exist or the which test fails.

If you can be sure that they haven't excluded the directory from Spotlight, a Spotlight search will be much quicker, and you wouldn't need to save the result:

image

(The command is mdfind -literal "(kMDItemDisplayName==ffmpeg && kMDItemKind=='Unix Executable File')", so you can easily see the quotes.)

And I'm sure there are other methods.

So yes -- there's a bunch of ways you can solve this problem, with varying degrees of success, once you've understood what the problem is.

4 Likes

always have new info to give out.
true professional👍
thanks all. really learned a lot.