What is bang dollar (!$) in Bash?

2019-01-22 12:39发布

问题:

Bang dollar seems to refer to the last part of the last command line.

E.g.

$ ls -l
 .... something
$ !$
-l
bash: -l command not found

I can find plenty on the dollar variables (e.g. $!) but not on this. Any explanation?

回答1:

That's the last argument of the previous command. From the documentation:

!!:$

designates the last argument of the preceding command. This may be shortened to !$.

Remark. If you want to play around with Bash's history, I suggest you turn on the shell option histverify like so:

shopt -s histverify

(you can also put it in your .bashrc to have it on permanently). When using history substitution, the substitution is not executed immediately; instead, it is put in readline's buffer, waiting for you to press enter… or not!


To make things precise, typing !$ is not equivalent to typing "$_": !$ is really a history substitution, refering to the last word of the previous command that was entered, whereas "$_" is the last argument of the previously executed command. You can compare both (I have shopt -s histverify):

$ { echo zee; }
zee
$ echo "$_"
zee
$ { echo zee; }
zee
$ echo !$
$ echo }

Also:

$ if true; then echo one; else echo two; fi
one
$ echo "$_"
one
$ if true; then echo one; else echo two; fi
$ echo !$
$ echo fi

And also:

$ echo zee; echo "$_"
zee
zee
$ echo zee2; echo !$
$ echo zee2; echo "$_"

And also

$ echo {1..3}
1 2 3
$ echo "$_"
3
$ echo {1..3}
1 2 3
$ echo !$
$ echo {1..3}

And also

$ echo one ;
$ echo "$_"
one
$ echo one ;
one
$ echo !$
$ echo ;

There are lots of other examples, e.g., with aliases.



回答2:

!$ can do what $_ does, except the fact that $_ does not store the value it returns (as its substitution) to history.

Here is an example.

With !$

za:tmep za$ ls -lad 
drwxr-xr-x  4 za  staff  136 Apr  6  2016 .
za:tmep za$ !$
-lad
-bash: -lad: command not found
za:tmep za$ history | tail -n 3
  660  ls -lad 
  661  -lad                     <<== history shows !$ substitution.  
  662  history | tail -n 3

With $_

za:tmep za$ ls -lad
drwxr-xr-x  4 za  staff  136 Apr  6  2016 .
za:tmep za$ $_
-bash: -lad: command not found
za:tmep za$ history | tail -n 3
  663  ls -lad
  664  $_         <<== history shows $_ and not its substitution. 
  665  history | tail -n 3
za:tmep za$ 

More options:

!^      first argument
!:2     second argument
!:2-$   second to last arguments
!:2*    second to last arguments
!:2-    second to next to last arguments
!:2-3   second to third arguments
!$      last argument
!*      all arguments