ping for indefinite amount of time and get its output in Python

后端 未结 3 1995
死守一世寂寞
死守一世寂寞 2020-12-12 02:10

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

相关标签:
3条回答
  • 2020-12-12 02:36

    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.

    0 讨论(0)
  • 2020-12-12 02:38

    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)
    ...
    
    0 讨论(0)
  • 2020-12-12 02:44

    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())
    
    0 讨论(0)
提交回复
热议问题