Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

bash shell: Can a control-c cause shell to write an empty file?

I have a bash shell script. It writes out to a text file. Most of the it works find if I stop the script with a control-c at the command level. Sometimes the file that's been written to such as

echo "hello world" >myfile.txt

will end up being empty. So it it possible that when I hit control-c to stop the shell script running it is caught it at the instance where it's opening a write to the file and before it puts anything in it, it doesn't get the chance and leaves it empty?

If that's the case. What can I do in the bash shell script so that it will exit gracefully after it's written to the file and before it gets a chance to write to the file again, because it's doing this in a while loop. Thanks!

like image 342
Edward Avatar asked Sep 07 '26 04:09

Edward


1 Answers

Yes, it's possible that you end up with an empty file.

A solution would be to trap the signal that's caused by ^C (SIGINT), and set a flag which you can check in your loop:

triggered=0

trap "triggered=1" SIGINT

while true
do
  if [ $triggered = 1 ]
  then
    echo "quitting"
    exit
  fi
  ...do stuff...
done

EDIT: didn't realize that even though the shell's own SIGINT handling will get trapped, it will still pass the SIGINT to its subprocesses, and they'll get killed if they don't handle SIGINT themselves.

Since echo is a shell builtin, it might survive the killing, but I'm not entirely sure. A quick test seems to work okay (file is always written, whereas without trapping SIGINT, I occasionally end up with an empty file as well).

As @spbnick suggests in the comments, on Linux you can use the setsid command to create a new process group for any subprocesses you start, which will prevent them from being killed by a SIGINT sent to the shell.

like image 142
robertklep Avatar answered Sep 10 '26 21:09

robertklep



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!