当我在 bash 命令行中输入此内容时
$ x=hi; printf '%s ' "$x" "${x[0]}"; echo "${_[0]}"
我有这个输出:
hi hi hi
- 为什么
"${_[0]}"
结果出现"hi"
在输出中? - 为什么我们可以使用该
"x[0]"
语法,既然它"x"
只是一个string
而不是一个array
?
答案1
该_
参数根据上下文有多种含义,但它绝不是数组。同样,在您的示例中,x
也不是数组。您之所以能够将其视为数组,是因为Bash 允许将非数组变量视为单元素数组。Bash 同样允许将数组变量视为非数组,并给出第一个元素。
作为man bash
说:
引用没有下标的数组变量相当于引用下标为 0 的数组。任何使用有效下标的变量引用都是合法的,并且
bash
会在必要时创建数组。
因此,其行为与或"${_[0]}"
相同,因为不是数组。同样,其行为与或相同,因为不是数组。"${_}"
"$_"
_
"${x[0]}"
"${x}"
"$x"
x
至于为什么_
持有价值hi
:在你所展示的用法中,执行参数扩展特殊_
参数产生最近的(同步执行的)命令的最后一个参数。
作为man bash
说_
:
在 shell 启动时,设置为用于调用在环境或参数列表中传递的正在执行的 shell 或 shell 脚本的绝对路径名。随后,扩展为前台执行的前一个简单命令的最后一个参数,扩展后。还设置为用于调用每个执行的命令的完整路径名,并放置在导出到该命令的环境中。检查邮件时,此参数保存当前正在检查的邮件文件的名称。
(重点是我的)
在这种情况下,最近执行的命令是:
printf '%s ' "$x" "${x[0]}"
传递给的参数printf
为:
%s
,仅执行了删除引号的操作。hi
,对其进行参数扩展,然后删除引号。hi
,对其执行了产生相同结果的更复杂形式的参数扩展,然后删除了引号。
答案2
$_
是一个特殊参数。它有多种用法,但在本例中,它指的是上一个命令的最后一个参数:
$ echo hi Hi Hello
hi Hi Hello
$ echo "$_"
Hello
由于$_
是变量,不是一个大批,该语法${_[0]}
只是无用的混乱,可以访问$_
:
$ echo "$_"
Hello
$ echo "${_[0]}"
Hello
文档
从man bash
:
$_
在 shell 启动时,设置为用于调用在环境或参数列表中传递的正在执行的 shell 或 shell 脚本的绝对路径名。 随后,扩展为前台执行的前一个简单命令的最后一个参数,扩展后。 还设置为用于调用每个执行的命令的完整路径名,并放置在导出到该命令的环境中。检查邮件时,此参数保存当前正在检查的邮件文件的名称。
我用粗体突出显示了与您的使用相关的部分。
答案3
正如其他人所提到的,${_[0]}
额外的输入${_}
可以缩写为$_
最常用的。
如前所述,它是一个变量,包含上次使用的命令的最后一个参数。实际应用如下:
$ ll /etc/lsb-release
-rw-r--r-- 1 root root 105 Feb 20 2019 /etc/lsb-release
$ cat $_
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=16.04
DISTRIB_CODENAME=xenial
DISTRIB_DESCRIPTION="Ubuntu 16.04.6 LTS"
在第一个命令中,最后一个参数是/etc/lsb-release
。在第二个命令中,参数是$_
,它会重复/etc/lsb-release
,因此您不必重新输入它。