bashshell:control-c能否导致shell写入空文件?

bashshell:control-c能否导致shell写入空文件?,bash,signals,bash-trap,Bash,Signals,Bash Trap,我有一个bashshell脚本。它会写出一个文本文件。若我在命令级别使用control-c停止脚本,大部分工作都会正常进行。有时已写入的文件,例如 echo "hello world" >myfile.txt 最终将是空的。所以,当我点击control-c停止shell脚本运行时,它可能会在打开文件写入的实例中被捕获,而在它放入任何内容之前,它没有机会将其保留为空 如果是这样的话。我可以在bashshell脚本中做些什么,以便它在写入文件之后,在有机会再次写入文件之前,能够优雅地退出,因

我有一个bashshell脚本。它会写出一个文本文件。若我在命令级别使用control-c停止脚本,大部分工作都会正常进行。有时已写入的文件,例如

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