Idle bash script until CTRL+c event is logged
Asked Answered
M

3

9

I have a bash script which does some work, which is done fairly quick. It should then idle until the user decides to terminate it, followed by some clean-up code.

This is why I trap the CTRL+c event with the following code:

control_c()
{
  cleanup
  exit 0
}

trap control_c SIGINT

But as my script is done quite quickly I never get to purposely terminate it, so it never gets to trap the CTRL+c and run the clean-up code.

I figured I could implement an endless do while loop, with sleep at the end of the script, but I assume there is a better solution.

How can I idle a script in bash, expecting the CTRL+c event?

Methuselah answered 2/5, 2016 at 21:22 Comment(3)
BTW, why not just put that in a generic EXIT trap? trap cleanup 0 and you're no longer depending on details of how you exit, as long as it isn't something like SIGKILL that can't be trapped at all.Ithunn
I don't think that that's possible in my case. The script enables a bunch of iptables rules which should only be in effective until the user decides it is no longer required.Methuselah
I'm not saying you don't wait for ctrl+c or enter or whatever, I'm just saying you use an EXIT trap rather than a SIGINT trap -- that way it still fires for exits that aren't SIGINT-based.Ithunn
I
13

Assuming you're connected to a TTY:

# idle waiting for abort from user
read -r -d '' _ </dev/tty
Ithunn answered 2/5, 2016 at 21:27 Comment(8)
Is directing /dev/tty necessary ?Luteal
I just tried this solution with and without < /dev/tty and the result seems to be identical.Methuselah
@123, it might be necessary, depending on what else the script is doing. Read rules from stidn, and run it as yourscript <firewall-rules, for instance, and then the read needs </dev/tty. If environment hasn't been specified (as it hadn't), I'm going to assume the worst (or make cases where I must assume something, like availability of a TTY at all, explicit).Ithunn
@boolean.is.null, ...see above; the </dev/tty is a robustness improvement, letting this be used even if the script is taking input from elsewhere.Ithunn
what if you aren't connected to any TTY but just locally what's the solution then? my script waits with this code but it doesn't do the rest of the script afterwardsPerfectionism
Oh, god bless u. You saved my day!Hygiene
@Perfectionism I used Brent Bradburn's answer in my shell script and it worked as expected, the script continued. You could try that.Roughish
I have a script with this solution at end, and another script that uses dialog that calls it as a job, the script with dialog gets crazy, like someone is constantly pressing Esc key!Walli
C
6

The following will wait for Ctrl-C, then continue running:

( trap exit SIGINT ; read -r -d '' _ </dev/tty ) ## wait for Ctrl-C
echo script still running...
Colotomy answered 22/10, 2019 at 16:44 Comment(1)
I haven't tested all scenarios, but this may be bash specific. In a GNU makefile, it may require SHELL = bash.Colotomy
W
1

I had problem with read -r -d '' _ </dev/tty, I placed it in a script to prevent it from exiting and killing jobs. I have another script that uses dialog and calls the first one as a job, when the script reaches read -r -d '' _ </dev/tty the parent script dialog have a very weird behavior, like someone is constantly pressing the Esc key, this makes the dialog try to quit.

What I recommend is to use sleep you can sleep for a long time like 999 days sleep 999d and if you need for sure for it to never stop you wan put it in a while loop.

Walli answered 21/8, 2021 at 16:34 Comment(1)
Some systems also support sleep infinity that sleeps for a very long timeVachell

© 2022 - 2024 — McMap. All rights reserved.