The task is: Try to send ping in python using the most basic form like \"ping 8.8.8.8\". After some time terminate the ping command (In a terminal, one will do Ctrl+C) and g
The second solution you have is great. There's just one issue with obtaining your desired behavior (getting the ping
's "conclusion"): You're sending the wrong signal to the process.
When you terminate the process from a shell, you traditionally send a SIGINT
signal. See "bash - How does Ctrl-C terminate a child process?". This allows the process to "wrap up" (e.g., cleaning up temprorary files, providing debug information).
import signal
# Open process
child.send_signal(signal.SIGINT)
# Provide some time for the process to complete
time.sleep(1)
# Echo output
Popen.terminate, which you're using now, sends a SIGTERM
instead of a SIGINT
.
Popen.terminate() sends SIGTERM on Posix OSs. However, by default CTRL+C sends SIGINT. So to get similar behavior like pressing CTRL+C, you can do something like this:
...
import signal
...
time.sleep(5)
child.send_signal(signal.SIGINT)
...
ping
will block in your code as soon as it fills its stdout OS pipe buffer (~65K on my system). You need to read the output:
#!/usr/bin/env python
import signal
from subprocess import Popen, PIPE
from threading import Timer
child = Popen(['ping', '8.8.8.8'], stdin=PIPE, stdout=PIPE, stderr=PIPE)
Timer(5, child.send_signal, [signal.SIGINT]).start() # Ctrl+C in 5 seconds
out, err = child.communicate() # get output
print(out.decode())
print('*'*60)
print(err.decode())