Shrikanth R K
Shrikanth R K

Reputation: 85

Capturing stdout from subprocess after sending SIGINT

I have a dtrace snippet run via python script and the dtrace snippet is such that it generates data when CTRL-C is issued to it. So I had a signal_handler defined in the python script to catch CTRL-C from user and relay this to the dtrace invocation done via subprocess.Popen but I am unable to get any output in my log file. Here is the script:

Proc = []
signal_posted = False

def signal_handler(sig, frame):
    print("Got CTRL-C!")
    global signal_posted
    signal_posted = True
    global Proc
    Proc.send_signal(signal.SIGINT) #Signal posting from handler

def execute_hotkernel():
    #
    # Generate the .out output file
    #
    fileout = "hotkernel.out"
    fileo = open(fileout, "w+")

    global Proc
    Proc = subprocess.Popen(['/usr/sbin/dtrace', '-n', dtrace_script], stdout = fileo)
    while Proc.poll() is None:
        time.sleep(0.5)

def main():
    signal.signal(signal.SIGINT, signal_handler)        # Change our signal handler
    execute_hotkernel()

if __name__ == '__main__':
    main()

Since I have a file hotkernel.out set in subprocess.Popen command for stdout I was expecting the output from dtrace to be redirected to hotkernel.out on doing a CTRL-C but it is empty. What is missing here?

Upvotes: 1

Views: 428

Answers (1)

Wyrmwood
Wyrmwood

Reputation: 3599

I have a similar issue.

In my case, it's a shell script that runs until you hit Control-C, and then prints out summary information. When I run this using subprocess.Popen, whether using a PIPE or a file object for stdout, I either don't get the information (with a file object) or it hangs when I try to run stdout.readline().

I finally tried running the subprocess from the interpreter and discovered I could get the last line of output after the SIGINT with a PIPE if I call stdout.readline() (where it hangs) and hit Control-C (in the interpreter), and then call stdout.readline() again.

I do not know how to emulate this in script, for a file output or for a PIPE. I did not try the file output in the interpreter.

EDIT: I finally got back to this and determined, it's actually pretty easy to emulate outside of python and really has nothing to do with python.

/some_cmd_that_ends_on_sigint
(enter control-c)
*data from stdout in event handler*

Works

/some_cmd_that_ends_on_sigint | tee some.log
(enter control-c)
*Nothing sent to stdout in event handler prints to the screen or the log*

Where's my log?

I ended up just adding a file stream in the event handler (in the some_cmd_that_ends_on_sigint source) that writes the data to a (possibly secondary) log. Works, if a bit awkward. You get the data on the screen if running without any piping, but I can also read it when piped or from python from the secondary log.

Upvotes: 1

Related Questions