Как отследить bash-скрипт - выход из состояния и почему он не удался

Иногда мне нужно выполнить команду следующим образом:

cat file.txt | awk ' NR%4 == 2 { print $1 }' | sort | uniq -c | sort -gr >>output.txt &

поверх больших файлов (размером от 2 до 32 ГБ). Я запускаю команду вечером, а когда я прихожу утром, output.txt иногда пуст, и процесс больше не выполняется.

Пожалуйста, как я могу отследить, что происходит? Почему и когда моя команда провалилась? Я знаю, что конвейер работает, потому что иногда он просто успешно завершается.

Большое спасибо!

ОБНОВЛЕНИЕ: я теперь думаю, что мой процесс был убит, потому что сервер, когда я выполняю эти вычисления, рекомендуется только для интерактивного использования. Если это правда, единственное, что я могу видеть из файла журнала, это то, что он не был успешным - не закончен.

Есть ли способ узнать, что мой процесс действительно был убит? Благодарю.

3 ответа

Первый шаг, инкапсулируйте этот скрипт в файл, а не запускайте его непосредственно в терминале (и потеряйте награду UUOC, пока мы на нем).

#!/bin/bash

{
awk 'NR%4 == 2 { print $1 }' file.txt | sort | uniq -c | sort -gr >>output.txt
} 2>error.log

Это захватывает все сообщения об ошибках в файле error.log, Затем вы можете добавить диагностическую информацию.

#!/bin/bash

{
date >&2
set -x
awk 'NR%4 == 2 { print $1 }' file.txt | sort | uniq -c | sort -gr >>output.txt
date >&2
} 2>error.log

Теперь у вас есть информация о том, когда и когда это началось и когда это закончилось. Так как ты в bashвы можете организовать захват состояний выхода каждого процесса в конвейере, если хотите, чтобы вы точно знали, какие команды вышли с каким состоянием. Вы можете или не можете получать сообщения о том, какой процесс был убит (если процесс был убит внешним сигналом), но если процесс умирает сам по себе, он должен напечатать сообщение о стандартной ошибке (вот для чего он предназначен, и почему так важно, чтобы ошибки выводились со стандартной ошибкой, а не со стандартным выводом).

С этим сценарием у вас есть стандартный вывод output.txt и стандартная ошибка собирается error.log; скрипт не использует стандартный ввод (данные поступают из file.txt). Таким образом, вы можете запустить это с nohup или просто в фоновом режиме с & безо всяких сомнений.

Вы можете предпочесть сделать имя file.txt в параметры командной строки; Вы можете сделать вывод и файлы журнала настраиваемыми. Вы можете предпочесть другой формат для вывода даты. Все это настраивается. Но ключевой момент заключается в том, чтобы поместить его в сценарий оболочки, чтобы вы могли обрабатывать такие вещи прямо и систематически.

использование screen , pv а также tee чтобы зафиксировать все ошибки, иметь индикатор выполнения и разрешить перезапуск с последней успешной команды, а не с нуля при ошибке.

Ты можешь использовать screen ( мультиплексор), а не в качестве фона вашего процесса. Таким образом, вы всегда можете просмотреть его статус и не пропустить сообщения об ошибках. Просто введите screen запустите команду без & и ударил CTRL-a,d, Вы можете выйти из системы. Чтобы позже просмотреть вывод, войдите (даже удаленно) и введите screen -r,

Furhtermore, если вы замените начальный cat с pv ( просмотрщик каналов), у вас будет индикатор выполнения, показывающий, сколько уже обработано:

pv -cN file.txt

и вы увидите что-то вроде

611MB 0:00:11 [58.3MB/s] [=>      ] 15% ETA 0:00:59

всякий раз, когда вы присоединяете screen процесс.

В качестве альтернативы / дополнения, вы можете вставить tee после команды, чтобы скопировать свой вывод в файл, прежде чем он будет распространен на следующий.

uniq -c | tee afteruniq.tmpfile | sort -gr

Файл afteruniq.tmpfile будет содержать результат uniq -c, Итак, вы знаете, что сработало, а что не удалось. Кроме того, вы можете возобновить цепочку после последнего успешного шага из tee д файл.

Вы должны перенаправить оба stderr а также stdout в ваш выходной файл.

Сделайте свою команду такой:

( awk 'NR%4 == 2{print $1}' file.txt| sort | uniq -c | sort -gr ) >> output.txt 2>&1 &

Сделать заметку о 2>&1 перенаправить stderr куда бы то ни было stdout собирается

Другие вопросы по тегам