Why 'echo $0' gives different result for two different terminals?

18,892

Solution 1

If the output of echo $0 command is -bash it means that bash was invoked as a login shell. If the output is only bash, then you are in a non-login shell.

man bash says somewhere at line 126:

A  login shell is one whose first character of argument zero is a -, or 
one started with the --login option.

See more about here: Difference between Login Shell and Non-Login Shell?.

Now, to explain why you get /bin/bash in the second case, I can say that a program (in your case your file manager, probably nautilus) or a script can change its own $0 to something else. As example see what's happening with $0 in my terminal (the same terminal all the time):

enter image description here

Solution 2

The difference is down to the way these were started. bash will initialise differently (read different startup scripts) depending on it's argv[0]. If the string starts with a hyphen - as in -bash then it runs as a login shell, if not, it will run as an interactive shell. It can also run as a non-interactive shell (ie. in a shell script).

To find out more, it's best to read the manual, man bash the INVOCATION section.

Solution 3

A shell is started when you login, but it's also started by programs like make, or when you run a shell script, or when you type :sh to vi, or when you create a new terminal window.

Originally, the shell read in ~/.profile when you logged in or ran su. This script would do things like announce whether you had new email, customize your erase and kill characters, and set and export the TERM and PATH variables. When started in almost any other context, the shell did not read ~/.profile, because doing most of those things would be redundant. You were expected to have exported any important shell variables to the new shell.

The way the shell knew whether to read in ~/.profile was to check whether the first character of argv[0], aka $0, was '-'.

Starting with csh, aliases were introduced. Aliases weren't exported in the environment. csh was designed to read in two different initialization scripts. ~/.login was read only when a user logged in, and the cue to do this was if argv[0] began with '-'. ~/.cshrc was read every time the shell was started. In general, one placed aliases in ~/.cshrc and everything else in ~/.login. csh also supported ~/.logout, which in most cases just cleared the screen and ran fortune.

Other shells adopted these same features. ksh would read in ~/.kshrc, bash would read in ~/.bashrc, and those were where you'd place your alias definitions.

So, to make a long story short, the application that spawns a shell gets to decide whether it should be a "login shell", in which case there's that '-' at the beginning, or a regular shell. In most cases, a shell that's going to be interactive is started as a login shell, and a shell meant just to run some commands, either as arguments or from a script, and then exit is a regular shell.

But it's all up to the whim of the application that starts the shell.

Share:
18,892

Related videos on Youtube

Beta4
Author by

Beta4

Updated on September 18, 2022

Comments

  • Beta4
    Beta4 over 1 year

    I opened a terminal on Ubuntu using Ctrl+Alt+T and a different terminal by going to a directory and then right clicking and choosing "Open in Terminal".

    I did an echo $0 in both cases.

    In the first case:

    $ echo $0
    -bash
    

    In the second case:

    $ echo $0
    /bin/bash
    

    Why this difference?

    • Admin
      Admin about 10 years
      $0 returns the name of the running process.
    • Admin
      Admin about 10 years
      Do you run two terminals with different user?
    • Admin
      Admin about 10 years
      I use the same user
    • Admin
      Admin about 10 years
    • Admin
      Admin about 10 years
      Are they actually different terminal emulators or just two instances of the same terminal emulator? Are they both the default terminal?