无法将特殊字符传递给 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 命令,ifconfig
和 sed
,没关系。但是,这些是 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.
我有这个命令可以获取从 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 命令,ifconfig
和 sed
,没关系。但是,这些是 shell 命令,并且在调用 subprocess.Poen
.
使用通信方式,最好用在这里。并将命令作为字符串而不是列表发送。
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.