Подстановка команд и переменная $PATH


Предыстория

Эта [статья] гласит :

Подстановка команд расширяется до вывода команд. Эти команды выполняются в подрешетке ..

Но руководство 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 была порождена во время замены команды. В этот момент я изменил 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, которая помогает оболочке находить двоичные файлы. Однако я смущен, когда читаю это вместе с заменой команд.

Если по $(..) порождается подрешетка, то переменная окружения PATH должна быть неповрежденной и указывать на двоичную (cut в этом случае) и поэтому bash не должен жаловаться, что он не может найти двоичный файл cut.

Вопрос

Как модификация PATH повлияла на подстановку команд здесь?

1 2

1 ответ:

Рассмотрим следующий пример:

$ 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 $
Короче говоря, подрешетки, порожденные $(...), наследуют ту же среду, что и родительская оболочка, даже если переменная не экспортируется. (Даже $$ - это то же самое, что и родительская оболочка.)