Suppress stdout Python SIGSTOP

440 views Asked by At

I'm trying to create a program that runs in the background but can be easily paused an unpaused. This can be done by starting another copy of prog.py and using pause flags. I can successfully pause and unpause my program this way. Using sig handlers I can output to stdout "Pausing program" "Resuming program"

I start the program to do work with a command like:

./prog.py -H foo -P bar -i 10

When I run the program as

./prog.py --pause 1

This causes a flag to be raised that calls

os.kill(%pid, signal.SIGSTOP)

everything pauses as it should but the first time (and ONLY the first time) I pause it I get this type of output to stdout:

 [2]+  Stopped                 ./prog.py -H foo -P bar -i 10

I have tried to suppress it by setting sys.stdout = '/dev/null' but that didn't seem to do it. It's not the end of the world if I can't figure it out, i'm just a bit annoyed and really only want to see pause and resume in the parent program. Any ideas?

2

There are 2 answers

0
fferri On

It's not python to print that line.

That line is printed by your shell (bash probably) when you suspend a job.

So you cannot suppress from within python.

The bad news is that you cannot suppress printing of that information from bash either. See the answer of How to suppress Terminated message after killing in bash?

0
Filipe Gonçalves On

As mentioned in other answers, this is printed by your shell. The shell monitors the status of every child process it forked. One of these child processes is your python program. When it is stopped, the shell is notified (with SIGCHLD), fetches the termination status of the child that stopped, and prints that message to let you know that one of the running jobs is now suspended.

I don't know if it's possible to configure bash to stop printing job status changes, but there's something else you can do: inside prog.py, just fork() and exit in the parent, leaving the child alive. This causes prog.py to become a child of init (as opposed to being a child of bash), and so bash will not care about it anymore.

I don't know Python, but here's an example in C:

#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>

int main(void) {
    pid_t f;
    if ((f = fork()) < 0) {
        perror("Unable to fork");
        exit(EXIT_FAILURE);
    }
    if (f == 0) {
        /* Child takes over */
        while (1); /* Just place your code here */
    }
    return 0;
}

I'm sure you can do something similar in Python.