Bash 命令替换和$PATH变量

Bash 命令替换和$PATH变量,bash,path,command-substitution,Bash,Path,Command Substitution,背景 上面说: 命令替换扩展为命令的输出。这些 命令在子shell中执行 但是bash手册在其命令替换部分中没有提到subshell。 下面是我的测试 $ ps PID TTY TIME CMD 26483 pts/25 00:00:00 bash 26866 pts/25 00:00:00 ps $ hpid="$(ps | grep bash)" $ echo "$hpid" 26483 pts/25 00:00:00 bash 26899 pts/25

背景

上面说:

命令替换扩展为命令的输出。这些 命令在子shell中执行

但是bash手册在其命令替换部分中没有提到
subshell

下面是我的测试

$ ps
  PID TTY          TIME CMD
26483 pts/25   00:00:00 bash
26866 pts/25   00:00:00 ps
$ hpid="$(ps | grep bash)"
$ echo "$hpid"
26483 pts/25   00:00:00 bash
26899 pts/25   00:00:00 bash
显示在命令替换期间生成了一个pid为26899的新shell。此时,我更改了
路径
环境变量

$ PATH="/some/rogue/path"
做了以下工作:

VAR="$(echo "Do|Die" | cut -d"|" -f 2)"
并得到以下错误:

Command 'cut' is available in '/usr/bin/cut'
The command could not be located because '/usr/bin' is not included in the PATH environment variable.
cut: command not found
我知道错误是由于修改了PATH环境变量,这有助于shell定位二进制文件。然而,当我将此与命令替换一起阅读时,我感到困惑。

如果通过
$(..)
生成了子shell,则PATH环境变量应该是完整的,并且应该指向二进制文件(
cut
,在本例中),因此bash不应该抱怨它无法定位
cut
二进制文件

问题


路径的修改如何影响此处的命令替换?

考虑以下示例:

$ export PS1='\$\$=$$ \$ '
$$=30862 $ a=123 # Note: No export a here.
$$=30862 $ echo $a
123
$$=30862 $ bash
$$=31133 $ echo $a # Subshell explicitly created does not have it.

$$=31133 $ exit
$$=30862 $ echo $(eval 'echo $a') # This subshell however does inherit it. The single quote ensures that this is not evaluated by parent shell.
123                               # echo $(echo $a) would probably cause $a to be evaluated by parent shell.
$$=30862 $

简而言之,
$(…)
生成的子shell继承与父shell相同的环境,即使未导出变量也是如此。(即使是
$
也与父shell相同。)

完美!您能否从文档中引用
继承与父shell相同的环境,
。没有问题。。慢慢来。我想你把子shell中对
PATH
的更改与子shell继承的对
PATH
的更改混淆了。@chepner:实际上我忽略了一个事实,即PATH是一个环境变量,不需要导出它,更改才会有效。啊,好的。请记住,“导出”变量实际上只是指标记其名称,以便将与该名称关联的值添加到任何子进程的环境中。将自动导出从环境初始化的环境变量。