Reputation: 11573
This program should echo the pid of sleep immediately:
import subprocess
subprocess.check_output("sleep 1 & echo $!", shell=True)
Running this on the shell directly, it immediately prints the pid, but running it in python, the &
is ignored and it takes 1 second before echo
is executed.
How can I get this to work with only one execution of check_output
(or another function of subprocess
)?
(This is a simplified example, in reality instead of sleep 1
I'd put my own executable)
Upvotes: 0
Views: 1176
Reputation: 77337
check_output
waits for the output pipes to close and sleep
has them too. You can redirect to /dev/null
for an immediate return.
subprocess.check_output("sleep 1 >/dev/null 2>&1 & echo $!", shell=True)
UPDATE
Its hard to tell if sleep 1
really did run in the background so I wrote a slightly larger test.
test.py - writes time to stdout
for 5 seconds
import time
for i in range(5):
print(time.strftime('%H:%M:%S'), flush=True)
time.sleep(1)
print('done', flush=True)
runner.py - runs the test redirecting stdout
to a file and monitors the file.
import subprocess as subp
import time
import os
# run program in background
pid = int(subp.check_output("python3 test.py >test.out 2>&1 & echo $!",
shell=True))
print("pid", pid)
# monitor output file
pos = 0
done = False
while not done:
time.sleep(.1)
if os.stat('test.out').st_size > pos:
with open('test.out', 'rb') as fp:
fp.seek(pos)
for line in fp.readlines():
print(line.strip().decode())
done = b'done' in line
pos = fp.tell()
print("test complete")
Running it, I get
td@mintyfresh ~/tmp $ python3 runner.py
pid 24353
09:32:18
09:32:19
09:32:20
09:32:21
09:32:22
done
test complete
Upvotes: 1