Ctrl+c in a sub process is killing a nohup'ed process earlier in the script

7,463

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.

Share:
7,463

Related videos on Youtube

Hashbrown
Author by

Hashbrown

Updated on September 18, 2022

Comments

  • Hashbrown
    Hashbrown over 1 year

    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

    • Hashbrown
      Hashbrown over 10 years
      Someone may have come across my issue; I think it is due to the handling within the database software, not on the shell. How would a program do this? How, then, might I stop it?
    • Piotr Dobrogost
      Piotr Dobrogost over 9 years
      nohup prevents the process from receiving SIGHUP signal whereas CTRL+C sends SIGINT signal. That's why nohup doesn't have the effect you expected.
  • Hashbrown
    Hashbrown over 10 years
    yes, but I don't know how to apply it. I tried placing the nohup line in a function which disowns itself, but that should be the same as nohup. I don't think this is a SIGHUP issue, as when I remove the less line, the script concludes with the server still running
  • MariusMatutiae
    MariusMatutiae over 10 years
    @Hashbrown pls see my edit
  • Hashbrown
    Hashbrown over 10 years
    Yeah I did a test as well, with a simple bash script being called instead of {SERVER} executable. And nohup just worked fine. See my comment on the question. I think it is purposefully listening somehow. Since its a propriety (and not well known) server I can't even say what it is so someone can go "oh its doing X, you need to do Y"