Почему трубопроводы и перенаправление работают с документами?

Сочетание переадресации с документом здесь кажется достаточно логичным:

$ bash > foo <<EOF echo Hello EOF $ less foo Hello 

Но с трубой она ведет себя по-другому:

 $ bash | tee foo <<EOF echo Hello EOF $ less foo echo Hello 

Что также странно, если вы сразу вводите «историю»:

 $ bash | tee foo <<EOF echo Hello EOF $ history $ history 1 ... 

То есть первая команда по-прежнему находится внутри вновь созданного bash. Что происходит? Почему труба ведет себя по-другому?

One Solution collect form web for “Почему трубопроводы и перенаправление работают с документами?”

Вы перенаправляете входной сигнал tee , а не bash . Использование:

 bash << EOF | tee foo echo Hello EOF 

Еще несколько примеров, иллюстрирующих, как это работает:

 bash << EO1 3<< EO\2 | tee 3<< EO3 foo 4<< EO4 fed (as a deleted temp file open in read-only mode) to bash fd 0 EO1 fed to bash fd 3 without $variable and $(cmd) expansion EO2 fed to tee fd 3 (not that tee does anything with its fd 3) EO3 fed to tee fd 4 (see how, like any redirection operator 3<< END can appear anywhere on the command line (for simple commands at least)) EO4 

Перенаправление составных команд:

 { head -n2; wc -l; } << EOF fed as fd 0 for the whole command group $(ps -e) EOF 

Или:

 if head -n1; then head -n2 fi << EOF 1 2 3 EOF 

Вы можете использовать один и тот же конечный токен:

 $ ls -l /proc/self/fd << E 3<< E >&2 | 3<< E 4<< E ls -l /proc/self/fd pipe heredoc> E pipe heredoc> E pipe heredoc> E pipe heredoc> E total 0 lr-x------ 1 stephane stephane 64 Feb 24 12:50 0 -> /tmp/zshLiVzp3 (deleted) lrwx------ 1 stephane stephane 64 Feb 24 12:50 1 -> /dev/pts/5 lrwx------ 1 stephane stephane 64 Feb 24 12:50 2 -> /dev/pts/5 lr-x------ 1 stephane stephane 64 Feb 24 12:50 3 -> /tmp/zshFLbQ7T (deleted) lr-x------ 1 stephane stephane 64 Feb 24 12:50 4 -> /proc/25749/fd/ total 0 lr-x------ 1 stephane stephane 64 Feb 24 12:50 0 -> pipe:[70735808] lrwx------ 1 stephane stephane 64 Feb 24 12:50 1 -> /dev/pts/5 lrwx------ 1 stephane stephane 64 Feb 24 12:50 2 -> /dev/pts/5 lr-x------ 1 stephane stephane 64 Feb 24 12:50 3 -> /tmp/zshL3KBp3 (deleted) lr-x------ 1 stephane stephane 64 Feb 24 12:50 4 -> /tmp/zshcJjS7T (deleted) lr-x------ 1 stephane stephane 64 Feb 24 12:50 5 -> /proc/25748/fd/ 

Что касается того, почему первая команда history запускается в этом новом bash в:

 $ bash | tee foo <<EOF echo Hello EOF $ history $ history 1 ... 

Это потому, что bash stdin все еще является терминалом, но его stdout – мертвая труба (на другом конце трубы tee перенаправил свой stdin из этого файла temp удаления, так что конец считывания этого канала закрыт).

bash не пишет свое приглашение или эхо того, что вы набираете на его stdout (мертвая труба), а на терминал, так что bash позволит вам вводить history в первом приглашении.

Однако эта history (которая является встроенной, так исполняемой процессом bash , а не дочерним), будет записывать свой вывод в этот мертвый канал. При этом процесс bash получит сигнал SIGPIPE (поскольку нет читателя) и умрет.

Следующее приглашение выдается вызывающей оболочкой.

  • Bash, вставить последний использованный аргумент текущей команды
  • Заменить колонку с результатом команды
  • Объединить поля в файл
  • Сохранить вывод -exec в текстовый файл
  • Печатать случайные строки в соответствии с порядком исходного файла
  • Более быстрый способ рекурсивно изменить владельца / группу?
  • Почему знак «меньше» не работает в качестве замены кошки в bash?
  • Позиционные параметры вызывающего абонента функции
  • Является ли «wait &» («wait ampersand») полезной (bash) оболочкой / shell-скриптом идиомой или техникой?
  • Как искать определенные разделы файла, а затем извлекать только соответствующую информацию в этом разделе?
  • Как безопасно отключить сетевой ресурс на Linux STB без сбоев (я получаю GSOD)?
  • Сколько элементов может хранить массив в unix-скрипте?
  • Linux и Unix - лучшая ОС в мире.