python shlex
核心函数
- shlex.split(s, comments=False, posix=True)
- 作用:将字符串按类似 Shell 的语法规则分割成参数列表,常用于安全处理命令行输入。
- 参数说明:
s(必需): 待分割的字符串(如 “ls -l ‘file name’”)。
comments(默认 False): 是否保留注释(以 # 开头的内容)。
posix(默认 True): 是否启用 POSIX 模式(正确处理引号和转义符)。
import shlex
print(shlex.split("echo 'Hello World'"))
print(shlex.split("ls #注释", comments=True))
- shlex.quote(s)
- 作用:对字符串进行安全 Shell 转义,防止命令注入攻击。
参数: - s: 需要转义的字符串(如包含空格或特殊字符的路径)。
filename = "file; rm -rf /"
safe_cmd = f"ls {shlex.quote(filename)}"
- 举例
import shlex
import subprocess
cmd_str = 'ls -l "my document.txt"'
args = shlex.split(cmd_str)
print("分割后的参数列表:", args)
result = subprocess.run(args, capture_output=True, text=True)
print("执行结果:", result.stdout)
cmd_str = 'echo "Hello | World" | grep "World"'
args = shlex.split(cmd_str)
result = subprocess.run(args, shell=True, capture_output=True, text=True)
print("分割后的参数列表:", args)
print("执行结果:", result.stdout)
* 关键说明:
* 若 shell=False(默认),管道符 | 会被视为普通字符导致失败
* 此处 shell=True 仅为演示管道功能,实际建议用 subprocess.PIPE 替代
cmd_str = 'python -c "import os; print(os.getenv(\'USER\'))"'
args = shlex.split(cmd_str)
result = subprocess.run(args, capture_output=True, text=True)
print("分割后的参数列表:", args)
print("用户环境变量值:", result.stdout.strip())
user_input = 'file with spaces.log'
cmd_str = f'grep "error" {shlex.quote(user_input)}'
args = shlex.split(cmd_str)
print("安全分割后的命令:", args)
subprocess.run(args)
cmd_str = 'find /logs -name "*.log" -exec grep -H "404" {} \;'
args = shlex.split(cmd_str)
result = subprocess.run(
args,
stdout=subprocess.PIPE,
text=True,
check=True
)
print("找到的404错误日志:")
print(result.stdout)
* 预期输出示例
* /logs/access.log:127.0.0.1 - [404] GET /missing-page
* /logs/nginx/error.log:[404] File not found: /old-link
- 总结
- 安全分割:shlex.split() 可正确处理空格、引号等特殊字符 13
- 避免命令注入:优先使用列表参数 + shell=False(默认)
- 管道处理:需要管道功能时配合 shell=True,但需严格验证输入
- 动态命令构建:使用 shlex.quote() 处理用户输入中的特殊字符