5

I'm thinking if my run.py script can act in two different mode. when in nohup mode: nohup python run.py & ,act like full log output mode.but in normal mode python run.py, act like log suppressed mode. So it will be tidy and clear for the user.

So.My question: How does my runnable python script knonw itself running in nohup mode or normal mode?

  • I've already tried `sys.argv` , `if __name__ == '__main__': print(sys.argv)`it only output `['run.py']` but nothing before `python` keyword in command `nohup python run.py`. – naughty fox Mar 08 '17 at 08:00
  • 1
    Does this work in your case? http://stackoverflow.com/questions/858623/how-to-recognize-whether-a-script-is-running-on-a-tty – kennytm Mar 08 '17 at 08:03
  • What OS are you targeting? Unix only? Linux or OS X? – alexis Mar 08 '17 at 08:06
  • 1
    @kennytm, `nohup` redirects stdout to a file, but it's common for scripts or commandlines to do so as well. Checking stdout is not a reliable method. – alexis Mar 08 '17 at 09:20
  • @alexis Sure. Your solution works specifically for nohup, while the linked solution works for anything that output to a non-tty. Depending on what OP want that one might actually be more appropriate. – kennytm Mar 08 '17 at 10:19
  • @alexis I'm using CentOS7 /bash/python3.5. it's a really great answer to deal with linux signal. – naughty fox Mar 08 '17 at 16:56

1 Answers1

5

The nohup command modifies the OS-level signal handling for the process it launches. This is not reflected in the command's arguments, but the process can query itself to check what actions or signal handlers are installed. Here's how to do it:

import signal

if signal.getsignal(signal.SIGHUP) == signal.SIG_DFL:  # default action
    print("No SIGHUP handler")
else:
    print("In nohup mode")

This will work on any Unix system, and probably on Windows (not tested). There are other ways to set a signal handler, from the shell or from within the program, but if you're just trying to distinguish between nohup and normal invocation, this will tell you all you need to know.

alexis
  • 48,685
  • 16
  • 101
  • 161
  • Would probably be more straightforward to check if it is set to SIG_IGN, no? – Hasturkun Mar 08 '17 at 08:27
  • 2
    Of course you can change the details to suit you, but I think checking for `SIG_DFL` is more robust. `nohup` on my system will set it to `SIG_IGN`, but who knows what it does elsewhere? The main question is whether the default handler (i.e. none) has been overridden. If the invoking shell has installed a handler function with `trap`, that's a `nohup`-like situation and my code will notice it. – alexis Mar 08 '17 at 08:41
  • 1
    Maybe point out that this doesn't address the side effect of `nohup` to run with lower `nice` priority, or the OP's (perhaps confused) example of running in the background with `nohup`, which is not a requirement (you can run in the background without `nohup`, and `nohup` doesn't strictly require you to run the job in the background, though it's rarely useful in practice not to). – tripleee Mar 08 '17 at 12:37
  • 1
    @tripleee, I just answered the question. It makes sense as asked, but you could be right. So caveat OP: `nohup` is for backgrounding a process and logging out. Output redirection and normal backgrounding are built into the shell, as special syntax. – alexis Mar 08 '17 at 13:01
  • 1
    @alexis: AFAIK, the shell can't set it to anything else, since anything other than `SIG_IGN` will get reset on `exec()` (Which makes sense, since whichever signal handler was there won't be present in the child, and you wouldn't want someone to run your process with an externally set, externally triggerable signal handler). – Hasturkun Mar 08 '17 at 16:19
  • @Hasturkun, you're right. (Ignoring a signal can get passed on if the invoking shell was called with the signal already ignored, but trapping to a function wouldn't.) Still I thought checking for deviation from the default behavior is the safest approach. – alexis Mar 08 '17 at 21:06