为什么 ping 在子进程中失败?

Why is ping failing in subprocess?

我在 subprocess.Popen() 中收到一条在命令行上运行良好的命令的错误。

命令很简单:

pax> ping -c2 127.0.0.1
PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
64 bytes from 127.0.0.1:icmp_seq=1 ttl=64 time=0.022 ms
64 bytes from 127.0.0.1:icmp_seq=2 ttl=64 time=0.060 ms

但是,当我尝试从 Python(交互式)执行此操作时,它就像我遗漏了地址:

>>> import shlex
>>> import subprocess
>>> args = shlex.split("ping -c2 127.0.0.1") ; print(args)
['ping', '-c2', '127.0.0.1']
>>> proc = subprocess.Popen(args, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
>>> print(proc.stdout.read()) ; print(proc.stderr.read())
b''
b'ping: usage error: Destination address required\n'

该错误消息完全我在尝试执行时得到的消息:

ping -c2

来自 shell 没有地址。

可能是什么原因造成的?

#!/bin/env python

import shlex
import subprocess

args = shlex.split("ping -c2 127.0.0.1")
cmdproc = subprocess.Popen(args, stdout=subprocess.PIPE)
print(cmdproc.stdout.read())

这就是你能做的。删除 shell=Truestdin=subprocess.PIPE

然后生成以下内容:

b'PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.\n64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.026 ms\n64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.043 ms\n\n--- 127.0.0.1 ping statistics ---\n2 packets transmitted, 2 received, 0% packet loss, time 999ms\nrtt min/avg/max/mdev = 0.026/0.034/0.043/0.010 ms\n'

进一步的解释,如果你使用 shell=True 参数,根据 [1] 你需要将参数指定为字符串,即“ping -c2 127.0.0.1”

并且由于您不需要从标准输入输入任何内容,因此您不需要标准输入。

[1] - https://docs.python.org/3/library/subprocess.html

shell=True 作为字符串传递命令时使用

proc = subprocess.Popen("ping -c2 127.0.0.1", shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

如果将 args 作为列表传递,则它必须是 shell=False

proc = subprocess.Popen(shlex.split("ping -c2 127.0.0.1"), shell=False, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

来自docs

If passing a single string, either shell must be True (see below) or else the string must simply name the program to be executed without specifying any arguments.