Не могли бы вы разработать акт по-другому, часть вашего вопроса?
devnull
Вы имеете ограниченный контроль над тем, как далеко prog2продвинулись при prog1выходе из-за внутренней буферизации, используемой для реализации канала, и как prog1и prog2по расписанию.
chepner
Также посмотрите на [В каком порядке запускаются команды по каналам?] (Unix.stackexchange.com/q/37508)
DK Bose
Ответы:
4
Общий ответ - нет. Это возможно для prog2выхода prog1даже до запуска (очевидно, что это не может произойти, если на prog2самом деле читает какой-то ввод, что вы ожидаете, если он будет использовать его в конвейере). Это определенно возможно для prog2выхода раньше prog1; это происходит, например, когда prog2поисковая программа завершает работу, как только находит совпадение, и в этом случае, prog1возможно, еще не закончены все данные.
Не существует прямого способа prog2получить статус выхода prog1или даже узнать, что prog1он вышел. Все, что prog2может знать, - это то, что prog1закрыл свой конец трубы, что он может сделать, не умирая.
Если вы хотите получить статус выхода prog1из prog2, есть два распространенных метода: вы можете записать его в файл или отправить через канал. Отправка выходного статуса в качестве последней строки переданных данных возможна. Вы должны следить за тем, чтобы не обрабатывать последнюю строку, пока не узнаете, что это последняя строка, т.е. пока вы не попытаетесь прочитать следующую строку.
{ prog1; echo $?;}|…
Вот пример, где правая часть представляет собой текстовый фильтр, который окрашивает каждую строку, содержащую слово «ошибка», в красный цвет. Если левая сторона выходит из строя, правая сторона выходит с тем же статусом.
{ prog1; echo $?;}| awk '
NR != 1 {
if (line ~ /[Ee][Rr][Rr][Oo][Rr]/) print "\033[31m" line "\033[0m";
else print line;
}
{line = $0}
END {exit($0)}
'
Я пытался, { command; echo ${PIPESTATUS[@]}; } | sort | ...чтобы статус выхода был первым в потоке. Это все очень интересно!
@lightÉ Это будет работать только в том случае, если ${PIPESTATUS[@]}отсортировано до чего-либо еще в выводе command. Если вы commandраспечатываете набор чисел или если он может распечатать произвольный текст, у вас возникнут проблемы: вы не сможете отличить его вывод от строки состояния.
Жиль "ТАК - перестань быть злым"
Спасибо, в самом деле, он только успешно сортирует статус успеха наверх, если команда не содержит 0 в своем выводе lol. Tgif / с.
2
Хотя вы можете в некоторых особых случаях (см. Другие ответы) вы не можете в каждом случае. Некоторые программы фильтрации будут продолжать работать, в то время как другие будут удерживать весь вывод, высвобождать его за один раз и затем выходить.
Для примера программы «просто продолжай», grepсервер будет, как и раньше tail -f /var/log/some_log_file. Использование sortв конвейере вызывает «остановку», так как sortбудет собирать входные данные, пока труба перед ним не закроется. Использование xargsдобавляет еще одну сложность: программы запускаются xargs(может начинаться много раз) частью конвейера или нет?
-1 потому что вы проголосовали за то, что цитировали неправильный ответ, и не сказали намного больше.
ctrl-alt-delor
@ Richard достаточно справедливо ... Я должен был перепроверить ... вот что случилось, если я
заставлю
1
Весь процесс в конвейере запускается перед любым выходом. Следовательно, prog2может потребоваться получить эту информацию после того, как она началась, она также должна будет задержать обработку до тех пор, пока она не выйдет prog1, это может остановить конвейер. Кажется, есть фундаментальные проблемы в выполнении того, что вы просите, а не ограничения ОС.
Вам, вероятно, нужно рассмотреть временный файл или поместить результат в переменную.
Пример для небольшого количества данных, используя переменную.
tmp=$(prog1)if test "z$PIPESTATUS"=="z0"then…else…fi
В твоих рассуждениях есть пробел. prog2запускается раньше, чем prog1завершается в целом, но может быть способ получить состояние вывода prog1во время его работы.
prog2
продвинулись приprog1
выходе из-за внутренней буферизации, используемой для реализации канала, и какprog1
иprog2
по расписанию.Ответы:
Общий ответ - нет. Это возможно для
prog2
выходаprog1
даже до запуска (очевидно, что это не может произойти, если наprog2
самом деле читает какой-то ввод, что вы ожидаете, если он будет использовать его в конвейере). Это определенно возможно дляprog2
выхода раньшеprog1
; это происходит, например, когдаprog2
поисковая программа завершает работу, как только находит совпадение, и в этом случае,prog1
возможно, еще не закончены все данные.Не существует прямого способа
prog2
получить статус выходаprog1
или даже узнать, чтоprog1
он вышел. Все, чтоprog2
может знать, - это то, чтоprog1
закрыл свой конец трубы, что он может сделать, не умирая.Если вы хотите получить статус выхода
prog1
изprog2
, есть два распространенных метода: вы можете записать его в файл или отправить через канал. Отправка выходного статуса в качестве последней строки переданных данных возможна. Вы должны следить за тем, чтобы не обрабатывать последнюю строку, пока не узнаете, что это последняя строка, т.е. пока вы не попытаетесь прочитать следующую строку.Вот пример, где правая часть представляет собой текстовый фильтр, который окрашивает каждую строку, содержащую слово «ошибка», в красный цвет. Если левая сторона выходит из строя, правая сторона выходит с тем же статусом.
источник
{ command; echo ${PIPESTATUS[@]}; } | sort | ...
чтобы статус выхода был первым в потоке. Это все очень интересно!${PIPESTATUS[@]}
отсортировано до чего-либо еще в выводеcommand
. Если выcommand
распечатываете набор чисел или если он может распечатать произвольный текст, у вас возникнут проблемы: вы не сможете отличить его вывод от строки состояния.Хотя вы можете в некоторых особых случаях (см. Другие ответы) вы не можете в каждом случае. Некоторые программы фильтрации будут продолжать работать, в то время как другие будут удерживать весь вывод, высвобождать его за один раз и затем выходить.
Для примера программы «просто продолжай»,
grep
сервер будет, как и раньшеtail -f /var/log/some_log_file
. Использованиеsort
в конвейере вызывает «остановку», так какsort
будет собирать входные данные, пока труба перед ним не закроется. Использованиеxargs
добавляет еще одну сложность: программы запускаютсяxargs
(может начинаться много раз) частью конвейера или нет?источник
Ответ: не напрямую.
@terdon проиллюстрировал, что код выхода предыдущей команды в конвейере должен быть отправлен в качестве явного параметра для следующей команды.
Помните, что канал - это просто отображение STDOUT предыдущей команды в STDIN следующей команды; коды выхода не выводятся в STDOUT (или STDERR).
источник
Весь процесс в конвейере запускается перед любым выходом. Следовательно,
prog2
может потребоваться получить эту информацию после того, как она началась, она также должна будет задержать обработку до тех пор, пока она не выйдетprog1
, это может остановить конвейер. Кажется, есть фундаментальные проблемы в выполнении того, что вы просите, а не ограничения ОС.Вам, вероятно, нужно рассмотреть временный файл или поместить результат в переменную.
Пример для небольшого количества данных, используя переменную.
источник
prog2
запускается раньше, чемprog1
завершается в целом, но может быть способ получить состояние выводаprog1
во время его работы.Чтобы закончить ответ Жиля ,
это подход.
prog2
может либо/tmp/prog1.status
или/tmp/prog1.status
периодически проверяйте наличие при чтении стандартного ввода.источник