使用Python子进程运行Linux的grep命令

3

我知道已经有关于如何在Python中使用subprocess运行Linux命令的帖子,但是对于这个命令,我无法正确理解语法。请帮忙。这是我需要运行的命令...

/sbin/ifconfig eth1 | grep "inet addr" | awk -F: '{print $2}' | awk '{print $1}'

好的,这是我目前拥有的内容,但会出现语法错误...

import subprocess
self.ip = subprocess.Popen([/sbin/ifconfig eth1 | grep "inet addr" | awk -F: '{print $2}' | awk '{print $1}'])

非常感谢您的帮助。


在Python中运行无用的grep毫无意义。Python已经配备了原生的字段提取功能,非常出色。 - tripleee
2
@tripleee 在这里根本不需要外部进程。从如何在Python中获取eth0的IP地址?调用get_ip_address('eth1')即可。 - jfs
1
如何使用subprocess.Popen通过管道连接多个进程? - jfs
2个回答

1

这已经被反复讨论多次了,但这里提供了一个简单的纯Python替代方案来替代低效的后处理。

from subprocess import Popen, PIPE
eth1 = subprocess.Popen(['/sbin/ifconfig', 'eth1'], stdout=PIPE)
out, err = eth1.communicate()
for line in out.split('\n'):
    line = line.lstrip()
    if line.startswith('inet addr:'):
        ip = line.split()[1][5:]

@whoopididoo:ip = re.search(br'inet addr:(\S+)', subprocess.check_output(['ifconfig', 'eth1'])).group(1) - jfs

0

以下是如何在Python中构建管道(而不是回归到Shell=True,这更难以保护)。

from subprocess import PIPE, Popen

# Do `which` to get correct paths
GREP_PATH = '/usr/bin/grep'
IFCONFIG_PATH = '/usr/bin/ifconfig'
AWK_PATH = '/usr/bin/awk'

awk2 = Popen([AWK_PATH, '{print $1}'], stdin=PIPE)
awk1 = Popen([AWK_PATH, '-F:', '{print $2}'], stdin=PIPE, stdout=awk2.stdin)
grep = Popen([GREP_PATH, 'inet addr'], stdin=PIPE, stdout=awk1.stdin)
ifconfig = Popen([IFCONFIG_PATH, 'eth1'], stdout=grep.stdin)

procs = [ifconfig, grep, awk1, awk2]

for proc in procs:
    print(proc)
    proc.wait()

最好使用Python中的re进行字符串处理。这样可以获取ifconfig的stdout。

from subprocess import check_output

stdout = check_output(['/usr/bin/ifconfig', 'eth1'])
print(stdout)

你在 awk1 上缺少重要的 -F: 选项。它会导致 Awk 将输入按冒号而不是空格进行分割。当然,整个管道可以简单地写成 awk '/inet addr:/ { print substr($2, 6) }' - tripleee
1
@tripleee,我已经添加了-F:选项。 - Peter Sutton
你应该在父进程中关闭管道,否则可能会挂起子进程。或者先启动最后一个命令,并将其stdin管道传递给前面命令的stdout - jfs
@PeterSutton:你应该从awk2获取输出(设置stdout=PIPE,调用communicate())。你仍然应该关闭管道(调用communicate()而不是wait(),以避免依赖垃圾回收来释放父进程中的文件描述符)。 - jfs

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接