了解`$ _`的含义


12

您能否解释一下Bash手册中有关以下内容的句子$_,尤其是粗体部分,也许还有一些示例?

  1. 在shell启动时,设置为用于调用环境或参数list中传递的正在执行的shell或shell脚本的绝对路径名。

  2. 随后,扩展,将扩展为上一个命令的最后一个参数。

  3. 还设置为用于调用每个执行的命令的完整路径名并将其放置在导出到该命令的环境中

  4. 检查邮件,这个参数保存邮件文件的名称。


4
-1问题不清楚,也没有彻底研究。你尝试了什么?您的期望与文字在哪里不一致?您不诚实地理解“随后”这个词吗?如果新用户要问相同的问题,我也会有相同的问题(尽管我对事物的确切运行方式有着类似的先天好奇心)。
杰夫·谢勒

Answers:


20

我同意这不是很清楚。

1.在Shell启动时,

  • 如果_变量在bash接收环境中,则bash保持不变。

    特别是,如果该bash外壳程序是由另一个bash 外壳程序调用的(尽管zshyash某些ksh实现也这样做),则该bash外壳程序会将_环境变量设置为正在执行的命令的路径(这是问题的第三点)。例如,bash由于另一个bashshell解释而调用if 来解释脚本:

    bash-script some args

    bash它将_=/path/to/bash-scrip在给的环境中传递,这就是变量bash-script的初始值$_ bash将在bash解释该脚本的外壳中。

    $ env -i _=whatever bash -c 'echo "$_"'
    whatever
  • 现在,如果调用的应用程序未传递_环境变量,则被调用的bash外壳程序将初始化$_argv[0]它接收到的自身,它可能是bash/path/to/bash/path/to/some-script或其他任何东西(在上面的示例中,就是/bin/bash脚本的爆炸性作用是#! /bin/bash/path/to/bash-script 取决于系统)。

    因此,该文本具有误导性,因为它描述了bash无法控制的调用方的行为。调用的应用程序 bash可能根本不会设置$_(实际上,只有一些shell和一些罕见的交互式应用程序execlp()才设置),或者可以将它用于完全不同的东西(例如ksh93将其设置为*pid*/path/to/command)。

    $ env bash -c 'echo "$_"'
    /usr/bin/env   (env did not set it to /bin/bash, so the value we
                   get is the one passed to env by my interactive shell)
    $ ksh93 -c 'bash -c "echo \$_"'
    *20042*/bin/bash

2.随后

随后的不是很清楚无论是。实际上,这是在当前shell环境中bash解释一个简单命令之后的结果。

  • 在使用交互式shell的情况下,这将是第一个简单的命令/etc/bash.bashrc,例如从中解释的命令。

    例如,在交互式外壳程序的提示下:

     $ echo "$_"
     ]      (the last arg of the last command from my ~/.bashrc)
     $ f() { echo test; }
     $ echo "$_"
     ]      (the command-line before had no simple command, so we get
             the last argument of that previous echo commandline)
     $ (: test)
     $ echo "$_"
     ]      (simple command, but in a sub-shell environment)
     $ : test
     $ echo "$_"
     test
  • 对于非交互式外壳$BASH_ENV如果$BASH_ENV未设置,则它将是馈入该外壳的代码中的第一个命令。

3.当Bash执行命令时

第三点有所不同,上面的讨论中已暗示了这一点。

bash,就像其他一些shell一样,它将_环境变量传递给它执行的命令,该命令包含bash用作execve()系统调用第一个参数的路径。

$ env | grep '^_'
_=/usr/bin/env

4.检查邮件时

MAILPATH变量的描述中更详细地描述了第四点:

“邮件路径”

用冒号分隔的文件名列表,shell会定期检查这些文件名以查找新邮件

每个列表条目都可以通过用“?”分隔邮件中的文件名来指定新邮件到达邮件文件时打印的邮件。在消息文本中使用时,“ $ _”将扩展为当前邮件文件的名称。

例:

$ MAILCHECK=1 MAILPATH='/tmp/a?New mail in <$_>' bash
bash$ echo test >> /tmp/a
New mail in </tmp/a>

4

试试这个简单的例子:

echo "$_"
echo "test"
echo "$_"

通过给出绝对路径(/home/$USERNAME/test.sh)来运行它;输出:

/home/$USERNAME/test.sh
test
test

第一个$_包含用于调用脚本的路径,第二个包含通往中间的第一个参数echo。对于列表中的第三项,如果您启动一个新终端并键入echo $_ ,它将显示一个包含的变量,该变量PATH通常用于在普通shell或.bashrs文件中的绝对路径中查找和调​​用命令(在Ubuntu机器中)。登录外壳。

对于bash手册页中的第四个项目:

在消息文本中使用时,$_将扩展为当前邮件文件的名称。


谢谢。(1)你能用例子解释第三种情况吗?(2)当我打开一个新的gnome终端选项卡时,输出echo $_EDITOR,为什么呢?接下来是什么情况?(3)您能举例说明如何检查邮件以及$_在这种情况下如何使用邮件吗?
2016年

打开您的.bashrc并注释掉那里的每一行。仅保留包含类似echo "test"或类似命令的一行。保存并关闭。然后bash立即运行echo $_。最后的回显应在输出中打印测试。
coffeMug

对于邮件部分,我还没有使用过Unix邮件,并且现在我的系统上还没有安装有效的邮件,因此无法举个例子。但是,如果你遵循的描述应该是显而易见MAILPATHlinuxcommand.org/lc3_man_pages/bash1.html
coffeMug

1
仅供参考,bash手册的最新规范是:gnu.org/software/bash/manual/bashref.html 。它是4.3版本,而linuxcommand页面是4.1。
杰夫·谢勒

1

对于案例2,一个例子值一千个单词:

mkdir my_long_dir
cd $_

做您想/希望的事。当我在命令行上时,给我一个简单的占位符,以免我不得不重复自己。

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.