什么时候 `_` 是 bash shell 的环境变量?

什么时候 `_` 是 bash shell 的环境变量?

Bash 手册说(手册页,我的重点):

当 Bash 调用外部命令时,该变量$_将设置为该命令的完整路径名,并且传递给其环境中的该命令。

和 (特殊参数):

_

$_,下划线。)在 shell 启动时,设置为用于调用在环境或参数列表中传递的 shell 或正在执行的 shell 脚本的绝对路径名。随后,在扩展后扩展至上一个命令的最后一个参数。还设置为用于调用执行的每个命令并放置在导出到该命令的环境中的完整路径名。检查邮件时,该参数保存邮件文件的名称。

  1. 在 bash shell 中,我运行:

    $ bash
    $ export | grep '_=' 
    

    根据手册,_应该是新bash shell的环境变量。export应该输出新 bash shell 的所有环境变量,但它不输出 _.所以我想知道是否_是新的bash shell的环境变量?

  2. 实际上在任何 bash shell 中,都会发生同样的事情

    $ export | grep '_='
    

    不输出任何内容。所以我想知道_bash shell 是否有一个环境变量?

  3. 用于比较:

    $ dash
    $ export  | grep '_='        
    export _='/bin/dash'
    

我的帖子的灵感来自迈克的评论斯蒂芬的回复

答案1

是的,_是新的 Bash shell 的环境变量;你可以通过运行看到

tr '\0' '\n' < /proc/$$/environ | grep _=

inside the shell:显示 shell 初始环境的内容。您不会在第一个 shell 中看到它,因为在启动之前没有先前的 shell 来设置它。

Bash 内部的扩展$_指的是_特殊参数,它扩展为上一个命令的最后一个参数。 (Bash 在内部通过使用_shell 变量来处理这个问题,每次解析命令时都会更新该变量,但这实际上是一个实现细节。每次解析命令时它都会“未导出”。)export不显示_,因为它不是标记为导出的变量;但是您可以在 的输出中看到它set

在第一个示例中,新的 Bash shell 解析并执行其启动文件中的命令,因此在运行时export | grep '_='_已被覆盖并标记为未导出。

dash示例中,它似乎没有执行任何启动文件,因此您将变量视为 Bash 在运行之前设置的环境变量dash

答案2

export不带参数列出所有导出的变量_不是变量,但被列为特殊参数

有点令人困惑,_也将是变量的有效名称,与其他特殊参数的名称不同。至少 Bash 4.4 允许对其进行赋值,没有任何抱怨。它只是没有用,因为特殊效果会立即覆盖该值。

答案3

并非每个 shell 变量都被标记为导出,如您在 的输出中看到的那样declare -p

bash标记为导出没有任何意义,$_因为它会自动将此变量添加到子进程的环境中其值与 shell 中的值(当时)不同。

将其显示为导出只会让用户对外部命令环境中将发生的情况感到困惑。

所有“运行时变量”均BASH*不会导出。

相关内容