使用 `_` 作为传递给命令的环境变量

Tim*_*Tim 3 environment-variables

来自 bash 手册

_

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

关于粗体的句子,斯蒂芬说

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

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

如何获取_任意命令的环境变量值而不是env, 以验证其值是该命令的可执行文件或脚本的路径名?

谢谢。

Ste*_*ris 7

$_值对子进程可见。您如何在孩子身上阅读它取决于您使用的语言。

例如在 C

#include <stdlib.h>
#include <stdio.h>

main()
{
  char *x=getenv("_");
  printf("%s\n",x);
}
Run Code Online (Sandbox Code Playgroud)

然而,程序不能依赖于$_被设置,因为其他 shell 可能会做不同的事情。

例如

$ env -i /bin/bash -c ./a.out
./a.out

$ env -i /bin/ksh -c ./a.out 
*31801*./a.out

$ env -i /bin/sh -c ./a.out 
Segmentation fault (core dumped)
Run Code Online (Sandbox Code Playgroud)

/bin/sh(在这个 Ubuntu 系统上是“破折号”)根本没有设置 $_,所以这个简单的程序崩溃了。哎呀:-)

您的调用程序根本看不到这个值$_。确实,在调用shell$_中设置为上一行的最后一个参数

$ ls /tmp > /dev/null
$ echo $_
/tmp

$ echo hello
hello
$ echo $_
hello
Run Code Online (Sandbox Code Playgroud)