_何时是bash shell的环境变量?


10

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'

我的帖子的灵感来自Mike的评论Stephane的回复


1
它是一个shell变量,已传递到命令的环境。它不一定要导出到Shell的环境中。 export是内置的,但是如果使用printenv _,它将向您显示如何调用它:/usr/bin/printenv在此系统上。
Toby Speight

请注意bash -c export | grep _=(来自Bash)显示父外壳如何调用该bash命令,即使$_在父窗口中未设置该命令也是如此。
Toby Speight

Answers:


13

是的,_是新Bash shell的环境变量吗?您可以通过运行看到

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

外壳内部:显示外壳初始环境的内容。您不会在第一个外壳中看到它,因为在启动之前没有先前的外壳可以对其进行设置。

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

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

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


谢谢。在新的bash shell中,为什么不export | grep '_='输出任何内容?在原始的bash shell中,为什么不tr '\0' '\n' < /proc/$$/environ | grep _=输出任何内容?
蒂姆(Tim)


9

export不带参数列出所有导出的变量_不是变量,而是作为特殊参数列出的。

令人困惑的是,它_也是变量的有效名称,这与其他特殊参数的名称不同。至少Bash 4.4允许分配它,而不会抱怨。这只是没有用,因为特殊效果会立即覆盖该值。


2
尝试将其_用作变量还是很有趣的;-)。它实际上是只写的,值立即丢失。
斯蒂芬·基特

1
另外,在内部Bash确实将其_视为变量,这就是为什么它出现在的输出中的原因set。但是据我所知,它不能标记为已导出。
Stephen Kitt '18

2
@StephenKitt,但Bash 4.4允许将其标记为只读。或整数。结果有些可笑。
ilkkachu

1
哈,很好的发现,那真是有趣!
斯蒂芬·基特

5

如您在的输出中所见,并非每个sh​​ell变量都被标记为已导出declare -p

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

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

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.