Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I've been a GNU/Linux user for years, but I can't figure out how to get usable process info on Mac.

I realized that $0 resolves to -bash in my login shell on Mac OS (Snow Leopard). This may break certain shell scripts that work fine in a Linux environment*.

Unfortunately, the manpage does not mention this fact

If bash is invoked with a file of commands, $0 is set to the name of that file. If bash is started with the -c option, then $0 is set to the first argument after the string to be executed, if one is present. Otherwise, it is set to the file name used to invoke bash, as given by argument zero.

Does the minus sign have a special meaning? Is there anything like /proc or a command line tool that could me help find the associated executable?

* Silly me. Of course, $0 will evaluate to the script name, as stated in the manual

share|improve this question
That is a hyphen, not a minus sign. – daknøk Jun 18 '12 at 12:13
Well, it's a hyphen-minus :) – user123444555621 Jun 18 '12 at 16:13
up vote 6 down vote accepted

The minus sign is the way the system tells the shell that it's invoked as a login shell and it should source ~/.profile (for Bourne-compatible shells). This is true on Linux, OSX and every other unix. A script would not be run in a login shell. For a script, $0 is the name of the script file (with or without the full path).

ADDED: The man page does explain (almost all) the different cases:

  • “If bash is invoked with a file of commands, $0 is set to the name of that file.” This covers scripts executed with bash myscript, as well as the indirect case where the script is executed directly and starts with #!/bin/bash.

  • “If bash is started with the -c option, then $0 is set to the first argument after the string to be executed, if one is present.” With -c, $0 is set to whatever the caller explicitly indicates.

  • “Otherwise, it is set to the file name used to invoke bash, as given by argument zero.” A login shell falls into this case: the shell is invoked with no arguments other than argument zero, so $0 is set to argument zero. It is login, su, or whatever program handled the login that chooses the arguments that it passed to the shell, and prepends a - to argument zero to tell the shell that it's a login shell.

Perhaps some explanation of argument zero is in order. When a program is executed, ultimately, an execve system call takes place. That system call takes three arguments:

  1. a file name, which must designate an existing, executable file. The kernel loads this file and transfers execution to it.

  2. an array of strings, called the arguments. Element zero in this array is by convention the same file name as above, or the just the file name without the full path if the location of the executable was determined by searching the $PATH environment variable. There are exceptions to this convention, such as login shells.

  3. another array of strings, called the environment.

When you call a program from the shell by typing myprogram foo bar, the arguments to execve are:
    1. /usr/bin/myprogram (assuming this is where the shell found myprogram)
    2. myprogram, foo, bar
    3. for each exported shell variable, the variable name followed by an equal sign and the value.

There is no general way to find the name of the executable file that was passed to execve from the running program. Under Linux, it's usually available as /proc/$$/exe where $$ is the process ID. Every unix makes it available to ps but the inner workings of ps differ widely. The executable may be deleted or renamed while the program is running; in this case ps might report obsolete information or no information.

share|improve this answer
Wow, I never knew that. But it seems correct indeed. Also, from the command line, $0 is the name of the shell. Never knew that either. :-) – Arjan Sep 12 '10 at 11:23
I never realized this happens in Liunx too. But it sure does. Okay, so IIUC the login process spawns a shell and assigns it an "arbitrary" name, contrary to what the manpage suggests. Is there no way to get the real information back? Even /proc/$$/cmdline contains a minus sign. How would ps do it? – user123444555621 Sep 12 '10 at 13:19
It's /proc/self/exe for the requesting process, and /proc/$$/exe for any process with PID $$; so readlink /proc/$$/exe will return shell's executable and readlink /proc/self/exe will return readlink's. – grawity Sep 12 '10 at 21:38

From man bash:

exec [-cl] [-a name] [command [arguments]]
If command is specified, it replaces the shell. No new process is created. The arguments become the arguments to command. If the -l option is supplied, the shell places a dash at the beginning of the zeroth argument passed to command. This is what login(1) does. ...

share|improve this answer
Thanks, I never used that. (Of course, technically, login does not call a bash internal. I just looked at the source: it's execle() in shell.c) – user123444555621 Sep 12 '10 at 15:59
@Pumbaa: I think the manpage describes behavior of login when calling a shell, not vice versa. – grawity Sep 12 '10 at 18:45
@grawity: That's correct. I posted that excerpt simply to show that this behavior (having a dash) is by design and recognized as something more broadly applicable and not something unusual. – Dennis Williamson Sep 12 '10 at 19:51

I am not sure what is going on with the -bash , but if you run bash again in the shell the value of $0 appears to be fine.

It seem to be something special os x is doing, cause if you run /usr/bin/login, which is the default script used by terminal program, the same problem with $0 appears.

share|improve this answer
True. Also, I just found that top -pid $$ returns bash, while ps $$ hooks up the minus sign. Very annoying. – user123444555621 Sep 12 '10 at 10:20
(Why the line break rather than a new paragraph...?) – Arjan Sep 12 '10 at 15:54

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .