$ _ vs! $. Последний аргумент предыдущей команды и перенаправление вывода

28

Вопрос о специальных переменных. Документация гласит:

!!:$

обозначает последний аргумент предыдущей команды . Это может быть сокращено до! $.


( $_подчеркивание.) При запуске оболочки задайте абсолютный путь, используемый для вызова оболочки или сценария оболочки, выполняемого в том виде, как он был передан в среде или списке аргументов. Впоследствии, расширяется до последнего аргумента предыдущей команды после раскрытия. Также задайте полный путь, используемый для вызова каждой команды, выполненной и помещенной в среду, экспортированную в эту команду.

Должна быть какая-то разница, которую я не могу уловить, потому что:

$ echo "hello" > /tmp/a.txt
$ echo "!$"
echo "/tmp/a.txt"
/tmp/a.txt

$ echo "hello" > /tmp/a.txt
$ echo $_
hello

В чем разница?

Loom
источник
4
! $ - это расширение истории, а не специальная переменная, поэтому я предполагаю, что код bash обрабатывает их по-разному.
Джефф Шаллер
2
У меня нет окончательного ответа на этот вопрос, но: ① язык оболочки Bourne это один из, возможно , , хотя бы внутренне непротиворечивого язык программирования до сих пор широко используется и сегодня. Попытка вывести общие принципы ни к чему не приведет. Вы просто должны запомнить все специальные правила. Сожалею. ② Запишите слова «после раскрытия» сразу после выделенной вами фразы в определении . Это важно. Это может не объяснить разницу, которая озадачивает вас, но это объясняет множество других способов и не одно и то же. $_$_!$
Звол

Ответы:

32

!$это слово, обозначающее расширение истории, оно расширяется до последнего слова предыдущей команды в истории . IOW, последнее слово предыдущей записи в истории. Это слово обычно является последним аргументом команды, но не в случае перенаправления. В:

echo "hello" > /tmp/a.txt

вся команда 'echo "hello" > /tmp/a.txt'появилась в истории и /tmp/a.txtявляется последним словом этой команды.

_является параметром оболочки, он расширяется до последнего аргумента предыдущей команды. Здесь перенаправление не является частью аргументов, передаваемых команде, поэтому helloпередается только аргумент echo. Вот почему $_расширили до hello.

_больше не является одним из стандартных специальных параметров оболочки . Он работает в bash, zsh, mkshи dashтолько тогда , когда интерактивными, ksh93только тогда , когда две команды находятся на разнесенных линии:

$ echo 1 && echo $_
1
/usr/bin/ksh

$ echo 1
1
$ echo $_
1
cuonglm
источник
1
Одним из эффектов !$расширения против $_параметра является то, что он echo $_всегда отображается в истории как echo $_, а echo !$показывает значение, до которого он был расширен. Например , echo one twoтогда echo !$, то нажатие на шоу echo two.
Джектоз