Почему адаптеры USB C -> DisplayPort сочетают -и -для каждого ноутбука?

Это то же самое, что и в:

В:

cmd1 | cmd2

Ваша оболочка ожидает завершения cmd1даже после завершения cmd2. Это касается не всех оболочек. Например, некоторые, такие как оболочка Bourne или Korn, этого не делают.

Когда cmd2умирает, конвейер на cmd1stdout становится сломанным , но это не прекращается cmd1мгновенно.

cmd1завершится при следующей попытке записи в этот канал. Затем он получит SIGPIPE, действие которого по умолчанию — завершить процесс.

С помощью cmd1== tail -f fileи cmd2== sed /w/q, tail -fбудет считывать последние 10 строк файла и записывать их на стандартный вывод (канала ), обычно в один фрагмент, если только строки не очень большие, и ждать, пока к fileбудет добавлено больше текста.

sed, который выполняется параллельно, будет ожидать ввода на своем стандартном вводе, читать его, обрабатывать строку за строкой и завершать работу, если есть строка, содержащая w.

Как только (или, возможно, с задержкой в ​​одну -строку с некоторой sedреализацией ), когда она находит эту строку, она завершается, но в это время tailуже записала в канал все, что он должен был ЗАПИСАТЬ, поэтому он не получит SIGPIPE, если какой-либо дополнительный текст не будет добавлен позже в файл (, после чего он сделает фатальныйwrite()).

Если вы хотите, чтобы cmd1завершилось, как только cmd2завершится,вам нужно что-то, чтобы убить его, как только cmd2завершится. Как с:

sh -c 'echo "$$"; exec tail -f test.txt' | {
  IFS= read pid
  sed /w/q
  kill -s PIPE "$pid"
}

Или сbash:

{ sed /w/q; kill -s PIPE "$!"; } < <(exec tail -f text.txt)
  

2020 Править

Как заметил @user414777, начиная с версии 8.28, реализация GNU tailв режимах отслеживания теперь не только опрашивает новые данные в отслеживаемом файле (s ), но также проверяет, соответствует ли его стандартный вывод становится сломанной трубой и выходит сразу после этого (или в течение одной секунды, если inotify не используется ), что делает обходные пути, описанные выше, ненужными.

Однако обратите внимание, что только GNU tailвыполняет такую ​​обработку, а не какая-либо другая реализацияtail(AFAIK )и никакая другая утилита (, даже реализации GNU ).

Итак, пока:

tail -f file | head -n1

Выйдет через одну строку,

tail -f file | tr '[:lower:]' '[:upper:]' | head -n1

, например, не обязательно, поскольку trне будет отслеживать, станет ли его стандартный вывод сломанным каналом, и поэтому умрет, только если он напишет что-то там после того, как канал, как обычно, сломался (и только в этот момент GNU tail -fзавершит работу ).

0
11.09.2020, 00:39
0 ответов

Теги

Похожие вопросы