Как продолжить каскадные конвейерные команды после сбоя

Я запускаю команду и манипулирую выводом с помощью своего собственного сценария, но я не хочу, чтобы основная команда останавливалась, когда мой сценарий дает сбой.

Например:

a-command | tee logfile.txt | myscript

когда мой скрипт дает сбой на полпути, я смотрю в logfile.txt, я нахожу, что он прерывается там, где мой скрипт перестал работать, но я хочу, чтобы команда a продолжалась, а logfile.txt чтобы иметь полный журнал, чтобы я мог отладить свой скрипт и исправить ошибку.

Как изменить мою команду, чтобы последняя часть конвейера рассматривалась как необязательная или игнорировалась в случае ошибок, чтобы первые две части (команда и тройник) завершили свою работу.

[EDIT] a-command— длительная задача, и мой сценарий в основном манипулирует выводом, чтобы улучшить отчет о состоянии во время выполнения команды. Поэтому я не хочу запускать свой скрипт после того, как a-командазавершит свою работу.

5
20.06.2020, 00:46
2 ответа
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" )
10
18.03.2021, 23:26

Тройник (в 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 $ 
10
18.03.2021, 23:26

Теги

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