Sometimes the output of ps -p $$ shows the absolute path to the currently-running zsh,

% ps -p $$
  PID TTY           TIME CMD
 1027 ttys005    0:00.11 /usr/local/bin/zsh

but not always:

% ps -p $$
  PID TTY           TIME CMD
 1507 ttys003    0:00.07 zsh -fl

What is a consistent way to get the path to the currently-running zsh?

EDIT (clarification): I'm interested in how to do this primarily in Darwin and Linux, but also in NetBSD.

  • What OS is it? It's unusual to get the arglist with ps without the -f option. – Stéphane Chazelas Aug 16 '13 at 20:40
  • @StephaneChazelas: Darwin; and the ps I'm using above is /bin/ps. For good measure, I ran /bin/ps -p $$, and got the same output as shown above. – kjo Aug 16 '13 at 20:54

The CMD output by ps is either the process name or the arguments passed to the command (including the first argument argv[0]). Though it bears some relation with the path of the executable, there's no guarantee for them to be linked.

On Linux:

print -r -- /proc/self/exe(:A)

On Darwin and Linux and possibly others:

lsof -ap"$$" -dtxt  -Fn | sed '2!d;s/.//;q'

But I don't know how reliable it is.

Another heuristic:

print -r -- ${${0#-}:c:A}

$0, like you see in the ps output contains the first argument that zsh received (argv[0]), or when passed a script as argument, that argument.

In the first case, typically, (by convention, there's no guarantee) that argv[0] would be either a path including a / (relative or absolute), or zsh (something without /) in which case the caller will have looked up zsh in his $PATH or his command hash table... If the path is relative, the above method will only work if the current directory has not changed since zsh was invoked. If there's no /, the method will only work if zsh is looking up the executable the same way as the caller did.

In the case of a script, it's the path of the script that will be returned instead of that of the interpreter (contrary to the first two solutions).

  • Thanks! BTW, on my system, the last two gave different answers, because the one given by the second is a symlink; I had to run sudo /bin/ls -l $( whence -p -- ${0#-} ) to get the true path (which then agreed with the results of the lsof approach). – kjo Aug 17 '13 at 0:18

You can use this command to get the absolute path of any program: which cmd

For example: which zsh

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.