14

Is there a way to tell whether my python script is running as a background process or not? I'm trying to differentiate between these two:

sudo ./myscript.py
sudo ./myscript.py &

Using sys.argv doesn't work - the ampersand doesn't count as an argument apparently. And what would be the effect of the following instead:

sudo python myscript.py
sudo python myscript.py &

I've had a look around, but everything seems to be about starting a background process from within a Python script, not whether the Python script itself is a background process. Thanks!

EDIT: The aim is to output a message (or not), i.e. "Press Ctrl+C to stop this script" if started normally, but don't display the message if started as a background process.

EDIT 2 I neglected to mention that this python script will be started by a script in /etc/init.d rather than from a terminal prompt. So the answer marked as correct does indeed answer the question as I phrased it and with the information given, but I thought I should point out that it doesn't work in the init.d scenario, to avoid any potential confusion in the future.

5
  • I don't think so. What do you want to achieve? Commented Jul 21, 2014 at 9:11
  • Thanks Aaron. I've added to the original request to clarify. Commented Jul 21, 2014 at 9:25
  • When the process is detached, reading from stdin will block it. Writing to stdout works, though. I don't know a way to check whether reading stdin would block, though. Commented Jul 21, 2014 at 9:30
  • 3
    Answer for C code: stackoverflow.com/questions/14894261/… Commented Jul 21, 2014 at 9:32
  • possible duplicate of Checking for interactive shell in a Python script Commented Jul 21, 2014 at 10:00

3 Answers 3

8

Based on the answer for C @AaronDigulla pointed to in a comment:

import os
import sys


def main():
    if os.getpgrp() == os.tcgetpgrp(sys.stdout.fileno()):
        print 'Running in foreground.'
    else:
        print 'Running in background.'


if __name__ == '__main__':
    main()
Sign up to request clarification or add additional context in comments.

3 Comments

Example given above worked perfectly, to a degree. :) I'm actually running the script using a script in /etc/init.d on Linux, rather than through a terminal. The example given works brilliantly when I start the Python script at a terminal prompt, but fails with OSError: [Errno 25] Inappropriate ioctl for device when run via the init.d script. I'll keep looking! :)
Wrap the call to os.tcgetpgrp in a try/except block and if throws an OSError then you know sys.stdout isn't a terminal. In that case it's probably safe to assume that no one is going to be able read the message. CTRL-C probably also won't work.
Technically, calling "nohup python code.py > output_file.txt" is not running the code in background, but this answer tells me so.
2

I saw the other solutions on other and decided to write a pure python solution. It reads from /proc/<pid>/stat rather than calling a subprocess.

from os import getpid

with open("/proc/{}/stat".format(getpid())) as f:
    data = f.read()

foreground_pid_of_group = data.rsplit(" ", 45)[1]
is_in_foreground = str(getpid()) == foreground_pid_of_group

The meanings of the columns of the stat file can be found here

Comments

1

Based on bash solution from this answer:

import os
import subprocess
pid = os.getpid()
if "+" in subprocess.check_output(["ps", "-o", "stat=", "-p", str(pid)]):
  print "Running in foreground"
else:
  print "Running in background"

1 Comment

I get this error: TypeError: a bytes-like object is required, not 'str'

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.