理解`$_`的含义

Tim*_*Tim 19 bash

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

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

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

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

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

Sté*_*las 23

我同意这不是很清楚。

1.在shell启动时,

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

    特别是,如果该bashshell 是由另一个bash shell调用的(虽然zshyash并且某些ksh实现也会这样做),那么该bashshell 会将_环境变量设置为正在执行的命令的路径(这是您问题中的第三点)。例如, ifbash被调用来解释脚本作为另一个bashshell 解释的结果:

    bash-script some args
    
    Run Code Online (Sandbox Code Playgroud)

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

    $ env -i _=whatever bash -c 'echo "$_"'
    whatever
    
    Run Code Online (Sandbox Code Playgroud)
  • 现在,如果调用应用程序未通过_环境变量,调用的bashshell将初始化$_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
    
    Run Code Online (Sandbox Code Playgroud)

2. 随后

随后的不是很清楚无论是。实际上,只要在当前 shell 环境中bash解释一个简单的命令即可

  • 在交互式 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
    
    Run Code Online (Sandbox Code Playgroud)
  • 对于非交互式 shell$BASH_ENV如果$BASH_ENV未设置,它将是馈送到该 shell 的代码中的第一个命令。

3. 当 Bash 执行命令时

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

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

$ env | grep '^_'
_=/usr/bin/env
Run Code Online (Sandbox Code Playgroud)

4.查看邮件时

第四点在MAILPATH变量的描述中有更详细的描述:

'邮件路径'

以冒号分隔的文件名列表,shell 定期检查新邮件

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

例子:

$ MAILCHECK=1 MAILPATH='/tmp/a?New mail in <$_>' bash
bash$ echo test >> /tmp/a
New mail in </tmp/a>
Run Code Online (Sandbox Code Playgroud)


dsz*_*dsz 9

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

\n
mkdir my_long_dir\ncd $_\n
Run Code Online (Sandbox Code Playgroud)\n

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

\n
\n

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

\n


cof*_*Mug 6

试试这个简单的例子:

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

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

/home/$USERNAME/test.sh
test
test
Run Code Online (Sandbox Code Playgroud)

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

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

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