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 $_helloWhat is the difference?
$_ vs !$. Last argument of the preceding command and output redirection
bash;shell;history expansion
!$ 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:echo hello > /tmp/a.txtthe 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 only hello is the argument passed to echo. That's why $_ expanded to hello._ is not one of shell standard special parameters anymore. It works in bash, zsh, mksh and dash only when interactive, ksh93 only when two command are on separated lines:$ echo 1 && echo $_1/usr/bin/ksh$ echo 11$ echo $_1