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

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

$ 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. Что происходит? Почему труба ведет себя по-другому?

  • Git alias multi-commands с; а также &&
  • grep переменная в выражении if
  • Как удалить строку на основе Delimeter в perl / Shell?
  • Как убить беглого кота?
  • Как избежать <или> в параметре в оболочке?
  • сценарий оболочки отлично работает при выполнении в терминале, но ошибки при запуске как параллельная программа
  • Как легко обновить список md5sums?
  • Как я могу распечатать все, кроме последних n символов в 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 (поскольку нет читателя) и умрет.

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

    Interesting Posts

    Как вернуть «on» или «off» для: chkconfig –list | grep httpd

    Заменить поле в одном файле на основе совпадения с другим полем в другом файле

    Как вставить новую строку после первой строки в файле, который похож на нее

    Совпадение простого регулярного выражения

    Поиск ключевых слов URL в GNOME 3

    Будет ли мой запрос MySQL продолжать работать, даже если мое ssh-соединение падает?

    Как проверить систему system.journal из другой системы

    Не удается установить вино и playonlinux

    сценарий оболочки отлично работает при выполнении в терминале, но ошибки при запуске как параллельная программа

    Более чистый способ удаления файлов в Linux, который включает в себя дату в качестве части имени файла

    Какие приоритеты можно использовать в модулях net_prio групп?

    Как я могу исправить строки, разбитые в неправильных местах?

    Неограниченная история в tmux

    Способ удаления новой строки (^ M) только из переменных, а не из файла

    Автоматизация резервного копирования с удаленного mysql

    Linux и Unix - лучшая ОС в мире.