Intereting Posts
Разрешения для Linux меняются автоматически исправление существующего архива flar приводит к «неизменному файлу», запуск docker всегда терпит неудачу с «нет такого файла или каталога» Вращение catalina.out с использованием формата timestamp с использованием logrotate. как каталина. $ date.out Использовать параметр скрипта в awk LSB: поднять сетевой интерфейс Переместить файлы в вложенных каталогах в папку dest, но сохранить basename и удалить структуру папок? Как контролировать кучу машин для использования ЦП с другого компьютера? Дефрагментация логических томов LVM2 Perl один вкладыш для поиска слов длиной более 63 символов mdadm.conf: устройства UUID, повторно подключаемый к другому кабелю, например Рекомендации по хорошим решениям MTA / groupware? Сбросьте шаблон слова в конце строки, используя sed Есть ли системная команда в Linux, которая сообщает о контенте? Erlang устанавливает на Freebsd 10 на Amazon ec2

Почему `jobs` и` dirs` работают в подстановке команд, подстановке процессов, конвейере и фоновых заданиях так же, как в исходной оболочке?

Если я прав, подстановка команд, подстановка процессов, конвейер и фоновые задания запускают команды, указанные внутри себя, в подоболочке, а не в исходной оболочке.

Но когда команды являются jobs или dirs , они выводятся точно так же, как когда они запускаются непосредственно в исходной оболочке:

 echo $( jobs ) cat <(jobs) jobs | less echo $( dirs ) cat <(dirs) dirs | less dirs & 

Это почему? Это потому, что подоболочки наследуют стек заданий и папок из исходной оболочки, или потому, что jobs и dirs запускаются в исходной оболочке, а не подshellх?

Но

 jobs & 

ничего не выводит. Почему он отличается от других команд? Благодарю.

Связано ли использование сценария в подshellх все еще позволяет командам в сценарии получить доступ к состоянию исходной оболочки?

Первая часть этого ответа состоит в том, что jobs и dirs являются встроенными, поэтому обычно bash просто запускает их непосредственно, а не вызывает subshell.

Это справедливо для случаев, когда есть каналы или подстановка команд ( $(jobs) ) или подстановка процессов ( <(jobs) ).

На самом деле это не так для запуска команды в фоновом режиме ( jobs & ) или явного запроса подоболочки (с ( jobs ) .)

Так что это объясняет последнюю часть вашего вопроса. Когда вы запускаете jobs в подоболочке, это действительно показывает задания для самой подоболочки.

Вот хорошая демонстрация этой концепции:

 $ sleep 1001 & [1] 15927 $ sleep 1002 & [2] 15940 $ jobs [1]- Running sleep 1001 & [2]+ Running sleep 1002 & $ ( sleep 1003 & jobs ) [1]+ Running sleep 1003 & $ jobs [1]- Running sleep 1001 & [2]+ Running sleep 1002 & 

Вы увидите, что в случае, когда jobs выполняются в подоболочке, будут отображаться только задания этой подоболочки (в данном случае sleep 1003 ).

Теперь, чтобы закончить, нам нужно обратиться к средней части вопроса, поэтому dirs & (которая действительно работает в подоболочке, как и ( dirs ) ) будет по-прежнему показывать каталоги, сохраненные в стеке pushd.

Оказывается, это происходит потому, что shell экспортирует список каталогов в специальную переменную массива DIRSTACK , которая затем наследуется подshellми. (Вы можете прочитать больше о DIRSTACK здесь .)

Один из способов продемонстрировать, как это работает, - использовать pushd на подоболочке и посмотреть, как это не влияет на стек каталогов исходной оболочки:

 $ dirs ~ $ pushd ~/tmp ~/tmp ~ $ ( dirs; pushd / >/dev/null; dirs ) ~/tmp ~ / ~/tmp ~ $ dirs ~/tmp ~ 

Я считаю, что следует рассмотреть все вопросы, о которых вы спрашивали.


ОБНОВЛЕНИЕ : Bash имеет специальное положение, чтобы сделать jobs | less jobs | less работы, поскольку команда jobs выполняется в текущей оболочке (что не относится к другим встроенным модулям.)

В коде есть проверка, которая хранится в переменной jobs_hack , которая позже проверяется, чтобы он выполнялся без создания jobs_hack оболочки и позволял передавать результаты jobs в другую команду.

Смотрите здесь для соответствующей части исходного кода, который реализует это. (По состоянию на bash 4.4)