The question is about special variables. Documentation says:
!!:$
designates the last argument of the preceding command. This may
be shortened to!$
.
(
$_
, an underscore.) 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 executed and placed in the environment
exported to that command.
There must be some difference I cannot catch, because:
$ echo "hello" > /tmp/a.txt
$ echo "!$"
echo "/tmp/a.txt"
/tmp/a.txt
$ echo "hello" > /tmp/a.txt
$ echo $_
hello
What is the difference?
Best Answer
!$
is a word designator of history expansion, it expands to the last word of previous command in history. IOW, the last word of previous entry in history. This word is usually the last argument to command, but not in case of redirection. In:the whole command
'echo "hello" > /tmp/a.txt'
appeared in history, and/tmp/a.txt
is the last word of that command._
is a shell parameter, it expands to last argument of previous command. Here, the redirection is not a part of arguments passed to the command, so onlyhello
is the argument passed toecho
. That's why$_
expanded tohello
._
is not one of shell standard special parameters anymore. It works inbash
,zsh
,mksh
anddash
only when interactive,ksh93
only when two commands are on separated lines: