1

Some terminal programs have a quit keystroke to safely stop their execution, for example:

Q+Enter

From this question I learned that the timeout command allows to send signals to a program after a specified amount of time but, as far as I know, none of those signals is equivalent to the quit keystroke that I am referring to.

The list of signals can be shown with the command kill -l:

 1) SIGHUP       2) SIGINT       3) SIGQUIT      4) SIGILL       5) SIGTRAP
 6) SIGABRT      7) SIGBUS       8) SIGFPE       9) SIGKILL     10) SIGUSR1
11) SIGSEGV     12) SIGUSR2     13) SIGPIPE     14) SIGALRM     15) SIGTERM
16) SIGSTKFLT   17) SIGCHLD     18) SIGCONT     19) SIGSTOP     20) SIGTSTP
21) SIGTTIN     22) SIGTTOU     23) SIGURG      24) SIGXCPU     25) SIGXFSZ
26) SIGVTALRM   27) SIGPROF     28) SIGWINCH    29) SIGIO       30) SIGPWR
31) SIGSYS      34) SIGRTMIN    35) SIGRTMIN+1  36) SIGRTMIN+2  37) SIGRTMIN+3
38) SIGRTMIN+4  39) SIGRTMIN+5  40) SIGRTMIN+6  41) SIGRTMIN+7  42) SIGRTMIN+8
43) SIGRTMIN+9  44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9  56) SIGRTMAX-8  57) SIGRTMAX-7
58) SIGRTMAX-6  59) SIGRTMAX-5  60) SIGRTMAX-4  61) SIGRTMAX-3  62) SIGRTMAX-2
63) SIGRTMAX-1  64) SIGRTMAX    

I would like to send the quit keystroke (echo the letter q) to a program after a certain period of time in order to stop a program safely.

How can I do it?

Jeff Schaller
  • 67,283
  • 35
  • 116
  • 255
  • I wouldn't say that pressing Q and enter is a common way to quit a program... Pressing Ctrl+D is far more common for programs that reads from standard input. A program that catches the TERM signal would additionally be able to gracefully quit if an unqualified kill was done on its PID. What is the program you want to do this for? – Kusalananda Mar 09 '18 at 17:32
  • @Kusalananda The program is gnss-sdr – codeaviator Mar 09 '18 at 17:35
  • 1
    How do you run the program? Is it a daemon that starts at boot? Do you interact with the program after starting it and before the timeout? Is it an idle timeout or a pure "after X minutes, end the program"? – Jeff Schaller Mar 09 '18 at 18:37
  • 1
    simplistic example for the simplistic case: (sleep 5; echo q) | cat – Jeff Schaller Mar 09 '18 at 19:06
  • It looks like it communicates via SysV message queues so you could also craft a program that queues up a stop message (assuming you know the queueid)
    • https://github.com/gnss-sdr/gnss-sdr/blob/31c6b6bc1da77c9589a04d52a38d2d20edacf06e/src/tests/unit-tests/control-plane/control_thread_test.cc#L85 ...
    – Anon Dec 23 '18 at 18:11

2 Answers2

3

Pressing a key and a signal are two different ways to communicate with a program. If there's a signal that's equivalent to a key press for a given program, that's because the author of the program designed it that way.

There are a few keys that the terminal itself translates into a signal, such as Ctrl+C to SIGINT. The program can change the terminal settings to capture those keystrokes itself rather than let the terminal translate them to a signal. The same terminal mechanism allows a key (normally Ctrl+D) to be translated to the end of input (only when it's pressed at the beginning of a line). This is not a signal: it means that the program receives an end-of-file indication when it tries to read input from the terminal.

When a terminal disappears, the kernel sends the signal SIGHUP to the foreground program running in the terminal, if any (and if it's a shell, the shell will re-send the signal to its foreground job). HUP comes from “(modem) hang-up”, and in the modern world applies in cases such as closing a terminal window in a GUI. Many programs catch this signal and shut down safely, so if it's more convenient for you to send a signal than to send input, you should try if this works for your program.

If you must send input, the easiest way is to run the program in Screen and to use screen -X to send input to the screen sesssion (example).

0

You can use $ consumer << DOCUMENT input in bash. If you want it with a nice delay, you might need to read (and analyze) the commands entered on line before piping them to your program.

analyze <<END
<your timed command>
  • I don't think heredoc is the right away to approach this issue given that it needs the keystorkes to be sent after a given time rather than piped in right away. Using a subshell pipe will probably yield results closer to what is wanted. A more extreme approach would be to use something like expect ... – Anon Dec 23 '18 at 18:02
  • I've meant analyze is a function that reads in the commands in the heredoc. Then these commands (in whatever syntax) are analyzed for the time component on that line. The output of that reading function can be piped into the command in question. – Michael Grieswald Dec 23 '18 at 18:07