Linux – Ctrl+c in a sub process is killing a nohup’ed process earlier in the script

bashlesslinuxnohup

I didn't know whether this belonged on SO (as it is a coding bug) but thought you guys would be more knowledgeable regarding the subtleties of the software used (so maybe even U&L could be considered).

Here's the minimal code script (see edits for full script, there's a reason I'm doing it this way);

#/bin/bash
nohup {SERVERCOMMAND} > currentOutput.log 2>&1 &

less +F currentOutput.log

What it tries to do is run a server in the background, which outputs to a log file.
Then I follow that log file using less +F. As you do, to exit this you must hit ctrl+c before you can hit Q.

What happens is, when I ctrl+c inside the less command (to stop tailing) it somehow kills the server started with nohup at the top! Nothing else is affected. I can shift+f to start tailing the log again (which gets no new info since the server is killed) and if I hit Q the rest of the script executes normally.

Do you know why this happens? How to avoid it/something else I should be using?


P.S.
The server program may be listening for a ^C, which may be the issue; is there something I can do to stop that? Like, when I just run {SERVERCOMMAND} on its own (in a blocking manner), I can hit ctrl+c, which doesn't immediately kill it; it prints Received ^C signal, shutting down (and then kills itself). This is what's happening when I ^C in less (A final Received ^C signal, shutting down is written to the log).


P.P.S
I've been trying a number of things (none worked);

  • trying to disconnect the stdin from the script by changing

    nohup {SERVERCOMMAND} > currentOutput.log 2>&1 &
    to
    nohup echo '' | {SERVERCOMMAND} > currentOutput.log 2>&1 &
    or
    nohup cat /dev/null/ | {SERVERCOMMAND} > currentOutput.log 2>&1 &
    
  • using stty intr ^G to replace the interrupt command, but then ctrl+g did exactly what ^C was doing anyway (so this may be an issue with my terminal emulator instead; konsole)

  • placing the nohup &/or the less line in parentheses (to make it a subshell)

  • running the script in xterm instead of konsole

Best Answer

I was right in thinking that it was SIGINT being sent to all processes when ctrl+c, but I was silly in thinking that making another process would bring it outside the process group (see my attempts in the P.P.S.).

This is, not only the exact use case, but the correct solution.

Because of how my script was structured the answer there didn't fit verbatim, this is the script now;

#/bin/bash

setsid {SERVERCOMMAND} > currentOutput.log 2>&1 &
less +F currentOutput.log

The server continues to output to the log file after I ctrl+c in less.

Thanks for everyone's time.

Related Question