Find the path of a shell command

Mats Wichmann mats at wichmann.us
Thu Oct 13 10:27:23 EDT 2022


On 10/12/22 14:51, Paulo da Silva wrote:
> Às 19:14 de 12/10/22, Jon Ribbens escreveu:
>> On 2022-10-12, Paulo da Silva <p_d_a_s_i_l_v_a_ns at nonetnoaddress.pt> 
>> wrote:
>>> Às 05:00 de 12/10/22, Paulo da Silva escreveu:
>>>> Hi!
>>>>
>>>> The simple question: How do I find the full path of a shell command
>>>> (linux), i.e. how do I obtain the corresponding of, for example,
>>>> "type rm" in command line?
>>>>
>>>> The reason:
>>>> I have python program that launches a detached rm. It works pretty well
>>>> until it is invoked by cron! I suspect that for cron we need to specify
>>>> the full path.
>>>> Of course I can hardcode /usr/bin/rm. But, is rm always in /usr/bin?
>>>> What about other commands?
>>>>
>>> Thank you all who have responded so far.
>>> I think that the the suggestion of searching the PATH env seems the 
>>> best.
>>> Another thing that I thought of is that of the 'which', but, to avoid
>>> the mentioned recurrent problem of not knowing where 'which' is I would
>>> use 'type' instead. 'type' is a bash (sh?) command.
>>
>> If you're using subprocess.run / subprocess.Popen then the computer is
>> *already* searching PATH for you.
> Yes, and it works out of cron.
>> Your problem must be that your cron
>> job is being run without PATH being set, perhaps you just need to edit
>> your crontab to set PATH to something sensible.
> I could do that, but I am using /etc/cron.* for convenience.
> 
>> Or just hard-code your
>> program to run '/bin/rm' explicitly, which should always work (unless
>> you're on Windows, of course!)
> It can also be in /bin, at least.
> A short idea is to just check /bin/rm and /usr/bin/rm, but I prefer 
> searching thru PATH env. It only needs to do that once.

I've read quite a bit of this thread without completely understanding 
the actual problem.

Crontabs have always been good at exposing the problem of "is my program 
expecting something to be set up which isn't guaranteed?" - usually 
environment variables, of which PATH is one. "But it worked from my 
login shell....".

Python's standard library has a tool for you:

shutil.which = which(cmd, mode=1, path=None)
     Given a command, mode, and a PATH string, return the path which
     conforms to the given mode on the PATH, or None if there is no such
     file.

     `mode` defaults to os.F_OK | os.X_OK. `path` defaults to the result
     of os.environ.get("PATH"), or can be overridden with a custom search
     path.



Since cron usually runs in a minimal environment, you should be able to 
use this to supply a decent value for PATH, look up the command you 
need, and then use that path to launch the command - or fail in some 
sort of graceful way if not found, so you can hear about it and make 
corrections.






More information about the Python-list mailing list