我有一个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
我的问题是,消息清理没有出现在终端上,也没有出现在日志文件中。
但是,如果我在不重定向输出的情况下调用程序,它就能正常工作。
发布于 2019-04-15 02:06:34
如果您不希望发生这种情况,请将tee
放在后台,这样它就不会成为获取SIGINT
的进程组的一部分。例如,使用bash4.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
发布于 2019-04-15 02:03:20
按^C
将SIGINT
发送到整个foreground process (当前管道或外壳程序“作业”),在tee
可以将处理程序的输出写到任何地方之前杀死它。您可以在shell中使用trap
使命令免受SIGINT
攻击,尽管这样做有明显的风险。
发布于 2020-07-11 20:29:38
只需使用tee
的-i
或--ignore-interrupts
选项即可。文档中写道:
-i, --ignore-interrupts
ignore interrupt signals
https://stackoverflow.com/questions/55678147
复制相似问题