Я запускаю команду и манипулирую выводом с помощью своего собственного сценария, но я не хочу, чтобы основная команда останавливалась, когда мой сценарий дает сбой.
Например:
a-command | tee logfile.txt | myscript
когда мой скрипт дает сбой на полпути, я смотрю в logfile.txt, я нахожу, что он прерывается там, где мой скрипт перестал работать, но я хочу, чтобы команда a продолжалась, а logfile.txt чтобы иметь полный журнал, чтобы я мог отладить свой скрипт и исправить ошибку.
Как изменить мою команду, чтобы последняя часть конвейера рассматривалась как необязательная или игнорировалась в случае ошибок, чтобы первые две части (команда и тройник) завершили свою работу.
[EDIT] a-command
— длительная задача, и мой сценарий в основном манипулирует выводом, чтобы улучшить отчет о состоянии во время выполнения команды. Поэтому я не хочу запускать свой скрипт после того, как a-команда
завершит свою работу.
a-command | tee logfile.txt | { myscript; cat >/dev/null; }
Сначала конвейер будет работать как обычно, пока myscript
не завершится (по какой-либо причине ). В этот момент cat
возьмет на себя чтение из tee
до тех пор, пока не перестанут поступать данные. Данные, считанные cat
, отбрасываются путем передачи их в /dev/null
.
Если a-command
завершается без myscript
завершения/сбоя первым, myscript
не сможет считать больше данных и предположительно завершит (? ). В тот момент, когда myscript
завершается, запускается cat
, но поскольку данных для чтения больше нет, он немедленно завершается, и конвейер завершается.
Ответ на комментарий TooTea о том, чтобы убедиться, что мы по-прежнему получаем правильный статус выхода для конвейера:
a-command | tee logfile.txt | ( myscript; err=$?; cat >/dev/null; exit "$err" )
Тройник (в Linux )имеет параметр, который игнорирует сбои канала.
a-command | tee --output-error=warn logfile.txt | myscript
Когда myscript дает сбой или уничтожается, команда -продолжает выполняться, а журнал продолжает расти.
Вы можете перезапустить свой скрипт и завершить его, когда он догонит последний полный блок журнала:
myscript < logfile.txt
Вы можете перезапустить свой сценарий, и он будет ждать дополнений, когда он наверстает упущенное.
tail -999999f < logfile.txt | myscript
Более сложный пример, содержащийся в сценарии Bash.
Регистраторпредставляет вашу команду -. Он генерирует 36 перестановок короткой строки, по одной в секунду. Весь вывод привязан к 593580.log.
awk представляет ваш "myscript". Он печатает подмножество ввода.
wdog — моя сторожевая утилита. -d 5 заставляет его отлаживать свои действия. -t 25 приводит к тайм-ауту управляемого процесса (awk )через 25 секунд с SIGUSR1. Это просто спасает меня от ручного запуска kill для имитации сбоя вашего скрипта. --Мне нравятся повторяющиеся тесты.
Когда awk исчезает, cat в той же составной команде получает возможность прочитать канал и копирует оставшиеся данные в дубликат журнала. Таким образом, вы можете повторно -запустить свой скрипт с полным журналом или только с необработанными данными, и вы можете сравнить два журнала, чтобы точно определить, где произошел сбой.
В качестве альтернативы вы можете cat >/dev/null
просто поддерживать канал в рабочем состоянии, чтобы регистратор продолжал работать.
Обе копии лог-файла кажутся строковыми -буферизованными :конечными -f показывают в реальном -времени.
Пример скрипта:
#! /bin/bash
logger () {
for Q in {0..1}{A..C}{A..F}; do
printf '%s\n' "${Q}"
sleep 1
done
}
AWK='
/C/ { printf ("awk %d %s\n", NR, $0); }
'
logger | tee 593580.log |
{
date
wdog -d 5 -t 25 awk "${AWK}"
date
cat > 593580.add
date
}
Пробный запуск:
paul $./593580
Thu 18 Jun 15:35:24 BST 2020
wdog 25.000| Thu Jun 18 15:35:49.574 2020
wdog 15:35:24.574| Started awk as 14035
awk 3 0AC
wdog 15:35:29.579| Tick
awk 9 0BC
wdog 15:35:34.583| Tick
awk 13 0CA
awk 14 0CB
awk 15 0CC
wdog 15:35:39.586| Tick
awk 16 0CD
awk 17 0CE
awk 18 0CF
wdog 15:35:44.591| Tick
awk 21 1AC
wdog 15:35:49.579| Tick
wdog 15:35:49.579| Timed out child 14035 with signal 10
wdog 15:35:49.580| Child 14035 terminated with signal 10
Thu 18 Jun 15:35:49 BST 2020
Thu 18 Jun 15:36:00 BST 2020
paul $