在 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 格式提取信息。
我正在尝试编写一个 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 格式提取信息。