“_=”是什么意思?

yod*_*ode 33 environment-variables set

运行后set -a var=99,我可以在输出中找到一句话set

...
TERM=xterm
UID=0
USER=root
VIRTUAL_ENV_DISABLE_PROMPT=1
_=var=99
colors=/etc/DIR_COLORS
...
Run Code Online (Sandbox Code Playgroud)

谁能告诉我“_=”是什么意思?

我注意到这echo $var不会给任何东西。如果我运行set -a,则set不会再次包含此变量。怎么了?

Bob*_*ger 39

下划线实际上是一个特殊的 shell 变量。您在这里看到的是下划线 ( _) 变量,其值为var=99。它是只读的,由 shell 维护。这是:

  • 在 shell 启动时设置,包含在参数列表中传递的正在执行的 shell 或脚本的绝对文件名。
  • 之后,它在扩展后扩展到上一个命令的最后一个参数。
  • 检查邮件时,此参数保存邮件文件的名称。
  • 它还被设置为执行并放置在导出到该命令的环境中的每个命令的完整路径名。

您的示例属于第二类。你输入:

set -a var=99  
Run Code Online (Sandbox Code Playgroud)

所以最后一个参数是var=99,这就是你设置的(你没有设置var99)。因此,_被设置为。这就是报道的内容:

_=var=99  
Run Code Online (Sandbox Code Playgroud)

这有点令人困惑,但第一个=表示对变量的赋值_,第二个是值的一部分。

还值得一提的是,该-a选项set将导致所有随后定义的变量被导出。


ImH*_*ere 19

_=在开始时的普通集装置的输出的线的,有一个被称为变量_在bash(下划线)。它的值是跟在=. 就像设置一个名为test_varto的变量12345将产生(在 bash 中):

$ test_var=12345

$ set | grep test_var
test_var=12345

$ declare -p test_var
test_var=12345
Run Code Online (Sandbox Code Playgroud)

这个特殊的 bash 变量将被设置为上一行的最后一个参数:

$ echo "Testing some" "values" "in the shell" "(only bash)" "_=myvar=hello"
Testing some values in the shell (only bash) _=myvar=hello

$ echo "$_"
_=myvar=hello

$ echo "Testing some" "values" "in the shell" "(only bash)" "_=myvar=hello"
Testing some values in the shell (only bash) _=myvar=hello

$ declare -p _
declare -- _="_=myvar=hello"
Run Code Online (Sandbox Code Playgroud)

请注意该输出中的两个 =


更长的描述

当您执行时set -a var=99,会发生三件不同的事情(与您的问题有关):

  1. 用于导出变量的设置选项 ( -a)(通过执行反向操作set +a)。
  2. 位置参数“设置”为选项后面的内容($1设置为var=99)。
  3. shell 变量下划线$_设置为最后一个参数(扩展)。

设置 -a

执行将所有后续(新的或更改的)变量set -a标记为导出(在所有 shell 中,除了和一些相关的 shell)。csh

$ set -a
$ myvariable=wer
$ env | grep myvariable
myvariable=wer
Run Code Online (Sandbox Code Playgroud)

要从此设置中恢复,只需将 更改-为 a +

$ set +a
$ unset myvariable              # to erase it from the environment if it
                                # was exported before the change of set +a
$ myvariable=456544654          # A new value of the variable.
$ env | grep "variable"         # No output means the var does not exist
                                # in the current environment
Run Code Online (Sandbox Code Playgroud)

设置 var=99

这实际上应该是set -- var=99为了避免使用以破折号 ( -)开头的值来解释选项(并且 set 有很多)。

将参数列表(位置参数列表)设置为--. 这在所有合理的 shell 中都是有效的(不在 csh 等人中)。位置参数用“$@”(或类似的“$*”,不等于)打印。

$ set -- a=1 b=2 c=3
$ echo "$@"
a=1 b=2 c=3
Run Code Online (Sandbox Code Playgroud)

#_=last_argument 并且,内部shell变量的值_更改为执行行的最后一个参数。这是不是真的在几乎所有的壳(JSH,灰,佳日,破折号,lksh,mksh,ksh93的,attsh当然CSH和tcsh的),除了庆典。

$ echo one two last argument
one two last argument

$ echo "$_"
argument

$ echo This is a new: last_argument
This is a new: last_argument

$ echo "$_"
last_argument
Run Code Online (Sandbox Code Playgroud)

请注意,in$_中的值为展开后的值:

$ a="A New_Argument"
$ echo Something else to test: "$a"
Something else to test: A New_Argument

$ echo "$_"
A New_Argument
Run Code Online (Sandbox Code Playgroud)

这就是为什么当你执行:

$ set -a myvar=99; set | grep 'myvar'
_=myvar=99
Run Code Online (Sandbox Code Playgroud)

您将获得 shell 变量“$_”的描述。这也有效:

$  set -a myvar=99; declare -p _
declare -- _="myvar=99"
Run Code Online (Sandbox Code Playgroud)


Dmi*_*yev 16

正确答案取决于您使用的外壳:

  • 因为bash,无论@BobEager 说什么都适用
  • for zsh,它只设置为上一个命令的最后一个参数,以及命令环境中命令的完整路径名
  • 一些 shell 喜欢dash只在运行交互式会话时设置这个变量

其他壳也可能有其他特殊性。因此,$_没有定义在POSIX,所以一个使用它的时候应该注意潜在的可移植性问题。

旁注:如果您打算将 99 的值分配给var并使其在后续子流程的环境中可用,则实现此目的的正确语法是:

export var=99
Run Code Online (Sandbox Code Playgroud)

  • 同样正确的语法是`unset var;set -a; 变量 = 99`。适用于所有合理的外壳(不是 csh 等)。 (2认同)

Sco*_*ott 8

我注意到echo $var不会给任何东西。… 发生了什么?

bash(1)的不太精细的打印中,我们发现

set[ --abefhkmnptuvxBCEHPT] [选项名称] [ arg ...]   [ ] [选项名称] [ arg ...]-o
set+abefhkmnptuvxBCEHPT+o

    ?????????
    指定选项时,它们会设置或取消设置 shell 属性。选项处理后剩余的任何参数都被视为位置参数的值,并按顺序分配给$1, $2, ... 。$n

这意味着,set -a var=99不会将环境变量设置var99; 它设置$1var=99. 尝试echo "$1"echo "$*",你会看到。