2

背景

这篇[文章]说:

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

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

我的测试如下

$ 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环境变量。

$ 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二进制文件。

问题

PATH这里的命令替换是如何修改的?

4

1 回答 1

5

考虑下面的例子:

$ 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,即使未导出变量也是如此。(甚至$$与父外壳相同。)

于 2016-06-30T04:52:52.093 回答