
Чтобы прояснить вопрос в заголовке, я понимаю, почему первый умирает. Я не понимаю, почему второй не умирает, просто для добавления a | cat
к телу цикла.
Также, возможно, связано,
while true; do echo y; done
умирает немедленно, когда я это делаю ^C
, но убивая
while true; do echo y | cat; done
часто требуется ударить ^C
больше одного раза. Иногда один раз срабатывает, иногда 2 или 3 раза срабатывает, а иногда мне нужно ^C
некоторое время подержать, чтобы он умер.
Оба варианта поведения встречаются как в bash, так и в zsh, хотя ^C
в bash первое встречается реже.
Для обоих поведений это не ограничивается добавлением трубы в cat
. | dd
, | tee
, и т.д. также вызывают их. Даже echo y | true
вызывает это. Кажется, это наличие любой трубы в теле цикла.
Почему наличие трубы в теле контура изменяет реакцию контура на сигналы?
решение1
В while true; do echo y; done | true
, поскольку echo
он встроен, у вас есть процесс подоболочки, который записывает y\n
в цикле в канал.
При true
возврате конец чтения этого канала закрывается, поэтому запись в конец записи приводит к SIGPIPE
доставке в процесс записи. Здесь это процесс подоболочки, который запускает цикл.
В while true; do echo y | cat; done | true
, это , cat
который записывает в канал. cat
обычно не встроен, и даже если бы он был, в оболочках, отличных от zsh и ksh, все компоненты каналов всегда запускаются в дочерних процессах.
Таким образом, здесь завершается только работающий процесс cat
, а процесс подоболочки, который запускает цикл, продолжает выполнять другие cat
процессы, которые завершаются, как только они записывают данные y\n
в свой stdout.
В ksh93/ksh2020, если вы это сделаете:
$ builtin cat
$ type cat
cat is a shell builtin
$ set -o pipefail
$ while true; do echo y | cat; done | true; kill -l "$?"
PIPE
На этот раз cat
встроен и выполняется в том же процессе, что и цикл (как и cat
самая правая команда в первой строке конвейера, а ksh не запускает ее в подоболочке), поэтому подоболочка выполняет true
выход и kill -l
подтверждает, что она была завершена сигналом SIGPIPE.