1. shell启动时,

1. shell启动时,

您能否解释一下 Bash 手册中关于 的以下句子$_,尤其是粗体部分,也许可以举一些例子?

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

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

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

  4. 什么时候检查邮件,该参数保存邮件文件的名称。

答案1

我同意这不是很清楚。

1. shell启动时,

  • 如果变量位于接收到的_环境中bash,然后bash保持不变。

    特别是,如果该shell 被另一个 shellbash调用(尽管如此,并且某些实现也这样做),那么该shell 会将环境变量设置为正在执行的命令的路径(这是问题中的第三点)。例如,调用 if 来将脚本解释为另一个 shell 解释的结果:bashzshyashkshbash_bashbash

    bash-script some args
    

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

    $ env -i _=whatever bash -c 'echo "$_"'
    whatever
    
  • 现在,如果调用应用程序未传递_环境变量,被调用的bashshell 将初始化$_为它argv[0]接收到的自身,可以是bash、 或/path/to/bash/path/to/some-script或其他任何东西(在上面的示例中,如果/bin/bash脚本的 she-bang 是#! /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. 随后

随后也不是很清楚。在实践中,一旦bash解释了简单的命令在当前的 shell 环境中。

  • 对于交互式 shell,这将是/etc/bash.bashrc例如解释的第一个简单命令。

    例如,在交互式 shell 的提示下:

     $ 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
    
  • 对于非交互式 shell,如果未设置,它将是$BASH_ENV输入到该 shell 的代码中的第一个命令。$BASH_ENV

3. Bash执行命令时

第三点有所不同,并在上面的讨论中有所暗示。

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

$ 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>

答案2

试试这个简单的例子:

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

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

/home/$USERNAME/test.sh
test
test

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

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

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

答案3

对于情况2,一个例子抵得上一千个字:

mkdir my_long_dir
cd $_

做你猜测/希望的事情。当我在命令行上时,给我一个简单的占位符,这样我就不必重复自己。


¹ 至少在这里对于这样一个简单的目录名称,并假设$CDPATH为空或未设置,并且$IFS尚未对其默认值进行修改。在一般情况下,您需要类似的东西mkdir -p -- $'-less tamed directory-/../foo/ *** Ah! *** /\n\n' && CDPATH= cd -P -- "$_",尽管这与本讨论正交。

相关内容