将信号处理程序的日志隐藏起来,当将stdout重定向到文件vi时

2024-04-26 22:33:28 发布

您现在位置:Python中文网/ 问答频道 /正文

我有这样一个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既没有出现在终端上,也没有出现在日志文件中。你知道吗

但是,如果我调用程序而不重定向输出,它可以正常工作。你知道吗


Tags: devimportecho程序signaltimedefnull
2条回答

如果您不希望发生这种情况,请将tee放在后台,这样它就不属于获取SIGINT的进程组。例如,在bash 4.1或更新版本中,可以使用自动分配的文件描述符启动process substitution,该描述符提供句柄:

#!/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

^CSIGINT发送到整个foreground process group(当前管道或shell“作业”),在tee可以在任何地方写入处理程序的输出之前终止。您可以在shell中使用trap来对命令进行免疫,尽管这会带来明显的风险。你知道吗

相关问题 更多 >