无法将特殊字符传递给 python 中的子进程

Can not pass special character to subprocess in python

我有这个命令可以获取从 Unix shell 返回的外部 IP 地址,所以我可以在我的服务器中使用它:

ifconfig | sed -En 's/127.0.0.1//;s/.*inet (addr:)?(([0-9]*\.){3}[0-9]*).*//p'

在我的 mac,终端 returns:

192.168.1.3

如何在 python 脚本中输出这个?我试过:

import subprocess

command = ['ifconfig', '|', 'sed', '-En', 's/127.0.0.1//;s/.*inet (addr:)?(([0-9]*\.){3}[0-9]*).*//p']
p = subprocess.Popen(command, stdout=subprocess.PIPE)
text = p.stdout.read()
retcode = p.wait()

我收到错误提示

ifconfig: interface | does not exist

提前致谢!

您的 shell 命令正在调用两个命令,ifconfig 的输出用作 sed 的输入。您可以使用 subprocess 来模拟此操作,但 sed 调用只是进行一些文本操作,因此更简洁的方法是在该步骤中使用 Python。例如:

import re
import subprocess

pattern = r'inet (?:addr:)?(?!127\.0\.0\.1)((?:\d+\.){3}\d+)'

p = subprocess.Popen(['ifconfig'], stdout=subprocess.PIPE)
text = re.search(pattern, p.stdout.read()).group(1)
retcode = p.wait()
ifconfig | sed -En 's/127.0.0.1//;s/.*inet (addr:)?(([0-9]*\.){3}[0-9]*).*//p'

您正在尝试调用 2 个 shell 命令,ifconfigsed,没关系。但是,这些是 shell 命令,并且在调用 subprocess.Poen.

时必须将 shell 关键字参数设置为 true

使用通信方式,最好用在这里。并将命令作为字符串而不是列表发送。

import subprocess

command = ' '.join(['ifconfig', '|', 'sed', '-En', 's/127.0.0.1//;s/.*inet (addr:)?(([0-9]*\.){3}[0-9]*).*//p'])
p = subprocess.Popen(command, stderr=subprocess.PIPE, stdout=subprocess.PIPE, shell=True)
stdoutdata, stderrdata = p.communicate()  #this is blocking
for line in stdoutdata:
    #do some thing with line

Popen.communicate(input=None)

Interact with process: Send data to stdin. Read data from stdout and stderr, until end-of-file is reached. Wait for process to terminate. The optional input argument should be a string to be sent to the child process, or None, if no data should be sent to the child.