bashshell:control-c能否导致shell写入空文件?
我有一个bashshell脚本。它会写出一个文本文件。若我在命令级别使用control-c停止脚本,大部分工作都会正常进行。有时已写入的文件,例如bashshell:control-c能否导致shell写入空文件?,bash,signals,bash-trap,Bash,Signals,Bash Trap,我有一个bashshell脚本。它会写出一个文本文件。若我在命令级别使用control-c停止脚本,大部分工作都会正常进行。有时已写入的文件,例如 echo "hello world" >myfile.txt 最终将是空的。所以,当我点击control-c停止shell脚本运行时,它可能会在打开文件写入的实例中被捕获,而在它放入任何内容之前,它没有机会将其保留为空 如果是这样的话。我可以在bashshell脚本中做些什么,以便它在写入文件之后,在有机会再次写入文件之前,能够优雅地退出,因
echo "hello world" >myfile.txt
最终将是空的。所以,当我点击control-c停止shell脚本运行时,它可能会在打开文件写入的实例中被捕获,而在它放入任何内容之前,它没有机会将其保留为空
如果是这样的话。我可以在bashshell脚本中做些什么,以便它在写入文件之后,在有机会再次写入文件之前,能够优雅地退出,因为它是在while循环中完成的。谢谢 是的,您可能会得到一个空文件 解决方案是捕获由^C(
SIGINT
)引起的信号,并设置一个可在循环中检查的标志:
EDIT:没有意识到,即使shell自己的SIGINT处理将被捕获,它仍然会将SIGINT传递给它的子进程,如果它们自己不处理SIGINT,它们将被杀死
由于echo是一个内置的shell,它可能会在杀戮中幸存下来,但我不能完全确定。快速测试似乎可以正常工作(文件总是被写入的,而在不捕获SIGINT的情况下,我偶尔也会得到一个空文件)
正如@spbnick在评论中所建议的,在Linux上,您可以使用该命令为启动的任何子进程创建一个新的进程组,这将防止它们被发送到shell的SIGINT终止。感谢您的帮助回复。那么上面的陷阱是control-c,是什么迫使它关闭它打开的文件?是否因为默认退出0而被称为“退出”?退出脚本的责任从shell转移到脚本本身(使用
if
语句)。因此,如果您在do stuff
中写入文件,它将继续这样做;在循环的下一次运行中,脚本检查^C是否被捕获,它是否顺利退出。尽管我刚刚注意到shell仍在将SIGINT传递给它的子进程。所以它可能根本不起作用:(将您不希望从^C接收SIGINT的命令放在一个单独的进程组中。在Linux上最简单的方法是使用“setId”命令,它在一个新会话中运行用其参数指定的命令,从而处理组。如下所示:setsid program\u writing\u files file\u towrite
。您可以启动另一个shell脚本,也可以像这样启动bash-c blah
。
triggered=0
trap "triggered=1" SIGINT
while true
do
if [ $triggered = 1 ]
then
echo "quitting"
exit
fi
...do stuff...
done