2

I am having troubles understanding variables {_,0} in the following example.

In script tmp.sh:

func() 
{
echo $_
echo $0
echo $1
}

calling tmp.sh with parameter x:

~$ ./tmp.sh x
./tmp.sh
./tmp.sh
x

and sourced tmp.sh with parameter x:

~$ . ./tmp.sh x
x
bash
x

As I understand $_ and $0, the later is for the first argument as in first example it's ./tmp.sh. Why it's equivalent to bash in the second example?

What does . expand to, and the former, which I am not sure about, return last parameter with sourced bash, and equivalent to $0 in unsourced bash. Is that the case?

3
  • @peterh not anymore!
    – Error
    Commented Nov 17, 2017 at 5:22
  • 1
    You are a good linux programmer, it is not a problem for you to type in complex structures of non-alphabetic characters. I think pressing the shift key shouldn't be a major problem for you. See how better looks your question now.
    – peterh
    Commented Nov 17, 2017 at 5:24
  • Sure, But i'm not native English speaker as I tend to forget such things
    – Error
    Commented Nov 17, 2017 at 5:27

2 Answers 2

5

Variables referenced by $N where N is a number are the positional parameters to your script. $0 is the first parameter, which is the script itself. $1 is the second parameter (referenced as 1 because bash is counting from zero, and humans start at 1), which is x.

$_ is a little bit weirder, because it's not specifically a positional parameter, but rather it's a special parameter that starts off as the full path to the command being run, but subsequently becomes the value of the last argument to the previous command, after any expansion. That's why it's the same as $0 in your first run, and in the second where you're sourcing the script it's expanding to the value x (which is the last argument to the previous command as interpreted by the sourcing).

For more information about these, start reading the bash manual at Section 3.4.1: Positional Parameters

The next section, 3.4.2, has information about the special variables, including $_.

1

From bash's man page Special Parameter section:

   0      Expands to the name of the shell or shell script.  This is set at shell initialization.  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 filename used to invoke bash, as given by argument zero.

Basically, $0 will give you the name of script if executing a script, or bash if interactive mode. Note that ., which is an alias for source, is not an executable, but a shell built-in, so it does not change the $0 value and keeps bash in interactive mode.

   _      At shell startup, set to the absolute pathname used to invoke the shell or shell script being executed as passed in the environment or argument  list.
          Subsequently,  expands  to the last argument to the previous command, after expansion.  Also set to the full pathname used to invoke each command exe‐
          cuted and placed in the environment exported to that command.  When checking mail, this parameter holds the name of  the  mail  file  currently  being
          checked.
1
  • i usually read man page, but for some reasons i assumed man bash doesn't exist :)
    – Error
    Commented Nov 17, 2017 at 5:28

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