!$ 是什么意思?

And*_*rew 37 bash command-history

我正在学习一个教程,它提到运行这个命令:

sudo chmod 700 !$
Run Code Online (Sandbox Code Playgroud)

我不熟悉!$。这是什么意思?

wch*_*gin 51

基本上,它是上一个命令的最后一个参数。

!$是上一个命令的“结束”。考虑以下示例:我们首先在文件中查找单词:

grep -i joe /some/long/directory/structure/user-lists/list-15
Run Code Online (Sandbox Code Playgroud)

如果 joe 在该用户列表中,我们希望将他从列表中删除。我们可以用那个长目录树作为参数来启动 vi,或者简单地将vi !$哪个 bash 扩展为:

vi /some/long/directory/structure/user-lists/list-15
Run Code Online (Sandbox Code Playgroud)

来源;顺便说一下,方便的指南)


这个!$标记和特殊的 shell 变量之间的区别毫无意义$_。事实上,两者都扩展到上一个命令的最后一个参数。然而,!$历史扩展期间$_被扩展,而在参数扩展期间被扩展。这样做的一个重要结果是,当您使用 时!$扩展的命令会保存在您的历史记录中。

例如,考虑击键

  • echo Foo Enter echo !$ Jar Enter Up Enter; 和

  • echo Foo Enter echo $_ Jar Enter Up Enter.

(唯一改变的字符是中间的$!$_。)

在前者中,当您按下 时Up,命令行会读取echo Foo Jar,因此写入标准输出的最后一行是Foo Jar

在后者中,当您按下 时Up,命令行读取echo $_ bar,但现在$_具有与以前不同的值——实际上,$_是 now Jar,因此写入 stdout 的最后一行是Jar Jar

另一个结果是_可以用于其他参数扩展,例如命令序列

printf '%s '    isomorphism
printf '%s\n'   ${_%morphism}sceles
Run Code Online (Sandbox Code Playgroud)

打印isomorphism isosceles。但是没有类似的“ ${!$%morphism}”扩展。

有关扩展在猛砸阶段的详细信息,请参阅EXPANSIONman 1 bash(这被称为shell扩展的网络版)。该HISTORY EXPANSION部分是分开的。

  • 好的。很高兴知道。此外,还有 Stack Exchange 是件好事。很难在 Google 上搜索类似 `!$` 的内容 (6认同)
  • 顺便说一句,在命令行上,您可以通过 `insert-last-argument` 插入上一个命令的最后一个参数,通常绑定到 `M-.`。 (4认同)

Evg*_*gin 5

严格来说!$是历史列表中最后一个命令的最后一个字。

word - 被 shell 视为一个单元的字符序列。单词可能不包括未加引号的元字符。

元字符 - 未加引号时用于分隔单词的字符。元字符是空格或以下字符之一:'|'、'&'、';'、'('、')'、'<' 或 '>'

空白 - 空格或制表符。

例子:

set -o history # enable command history
set -o histexpand # enable ! style history substitution

HISTSIZE=10

# save all lines on the history list    
HISTCONTROL=
HISTIGNORE=

date
echo !$ # prints date

date>/dev/null
echo !$ # prints /dev/null

echo a b c>/dev/null
echo !$ # prints /dev/null

HISTCONTROL=ignorespace # lines which begin with a space character are not saved in the history list
echo a b c
 echo d e f # space at the beginning
echo !$ # prints c
Run Code Online (Sandbox Code Playgroud)