在 Python 程序中使用 shell 命令执行正则表达式时出现问题

Problem executing regex with a shell command inside Python program

我正在尝试编写一个 Python 脚本来在与服务器的高入站连接发生时自动执行一些任务。

所以其中一部分是收集服务器上所有的IPv4地址。

命令有助于列出。

# ip a s eth0 | egrep -o 'inet [0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | cut -d' ' -f2
198.168.1.2
198.168.1.3
198.168.1.4

我在 python 脚本中执行 shell 正则表达式部分时遇到的问题。

#!/usr/bin/env python3
import os
ipv4_regex='[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}'
os_cmd = 'ip a s eth0 | egrep -o 'inet ipv4_regex' | cut -d' ' -f2'
os.system(os_cmd)

但是输出错误:

# ./dos_fix.py
  File "./dos_fix.py", line 4
    os_cmd = 'ip a s eth0 | egrep -o 'inet ipv4_regex' | cut -d' ' -f2'
                                     ^

为了查看它是否是由于 egrep 和管道之间的任何空格中断,我试图用反斜杠转义那些引号,但没有成功。

#!/usr/bin/env python3
import os
ipv4_regex='[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}'
os_cmd = 'ip a s eth0 | egrep -o \'inet ipv4_regex\' | cut -d\' \' -f2'
os.system(os_cmd)

我在这里错过了什么?

使用双引号,不要转义。

在正则表达式中,使用原始字符串:r'contents'.

os.system has some limitations. subprocess好多了。

#!/usr/bin/env python3
import os

ipv4_regex = r'[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}'
os_cmd = f"ip a s eth0 | egrep -o 'inet {ipv4_regex}' | cut -d' ' -f2"
os.system(os_cmd)

您尝试执行的子进程不知道 ipv4_regex 是一个 Python 变量,或者它的值可能是什么。您只是在字面上搜索该字符串,i p v 4

无论如何,一个更好的解决方案是在 Python.

中进行尽可能多的处理
import subprocess
import re

ipv4_regex=re.compile(r'inet [0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}')

for line in subprocess.run(
    ['ip', 'a', 's', 'eth0'],
    capture_output=True, text=True, 
    check=True
).stdout.split('\n'):
    m = ipv4_regex.search(line)
    if m:
        print(line.split()[1])

(我不得不猜测一下您的脚本应该做什么,因为您使用的语法无效。)

正如 os.system 文档已经告诉您的那样,subprocess 用途更广,通常推荐使用 os.system。特别是,如果您希望子进程的输出可供 Python 使用,而不仅仅是显示在控制台上,则您 需要 使用 subprocess。它还使您可以更好地控制子流程,包括在不需要时不使用 shell 的能力。 (另请参阅 Actual meaning of shell=True in subprocess

注意使用或“原始”字符串将实际的反斜杠放入正则表达式; Python 对源代码中的字符串进行自己的反斜杠处理,因此如果不使用 r'...' 语法,则必须将反斜杠加倍以在字符串中放入文字反斜杠。

如果您的目标平台是 Linux,可能更好的解决方案仍然是直接从 /proc 文件系统中以 machine-readable 格式提取信息。