Журналы от обработчика сигнала скрыты при перенаправлении stdout в файл через тройник - PullRequest
1 голос
/ 14 апреля 2019

У меня есть такая программа на Python:

import signal, time

def cleanup(*_):
    print("cleanup")
    # do stuff ...
    exit(1)

# trap ctrl+c and hide the traceback message
signal.signal(signal.SIGINT, cleanup)

time.sleep(20)

Я запускаю программу через скрипт:

#!/bin/bash

ARG1="$1"

trap cleanup INT TERM EXIT

cleanup() {
    echo "\ncleaning up..."
    killall -9 python >/dev/null 2>&1
    killall -9 python3 >/dev/null 2>&1
    # some more killing here ...
}

mystart() {
    echo "starting..."
    export PYTHONPATH=$(pwd)
    python3 -u myfolder/myfile.py $ARG1 2>&1 | tee "myfolder/log.txt"
}

mystart &&
cleanup

Моя проблема в том, что сообщение cleanup не отображается ни в терминале, ни в файле журнала.

Однако, если я вызываю программу без перенаправления вывода, она работает нормально.

Ответы [ 2 ]

2 голосов
/ 14 апреля 2019

Если вы не хотите, чтобы это происходило, поместите tee в фоновом режиме, чтобы оно не входило в группу процессов, получающих SIGINT.Например, в bash 4.1 или новее вы можете запустить замену процесса с автоматически назначаемым файловым дескриптором, предоставляющим дескриптор:

#!/usr/bin/env bash
#              ^^^^ NOT /bin/sh; >(...) is a bashism, likewise automatic FD allocation.

exec {log_fd}> >(exec tee log.txt)  # run this first as a separate command
python3 -u myfile >&"$log_fd" 2>&1  # then here, ctrl+c will only impact Python...
exec {log_fd}>&-                    # here we close the file & thus the copy of tee.

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

python3 -u myfile > >(trap '' INT; exec tee log.txt) 2>&1
2 голосов
/ 14 апреля 2019

Нажатие ^C отправляет SIGINT всему процессу переднего плана group (текущий конвейер или «задание» оболочки), убивая tee, прежде чем он сможет записать вывод от вашего обработчика в любом месте. Вы можете использовать trap в оболочке для иммунизации команды против SIGINT, хотя это сопряжено с очевидными рисками.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...