本文目录导读:

在Python中,有几种方式可以在运行时执行系统命令并获取输出,这里介绍最常用的几种方法:
subprocess 模块(推荐)
基础用法
import subprocess
# 获取命令输出
result = subprocess.run(['ls', '-la'], capture_output=True, text=True)
print(result.stdout) # 标准输出
print(result.stderr) # 错误输出
# 检查返回值
if result.returncode == 0:
print("命令执行成功")
常用参数说明
# 设置工作目录
result = subprocess.run(['ls'], cwd='/tmp', capture_output=True, text=True)
# 设置超时时间
try:
result = subprocess.run(['sleep', '5'], timeout=3)
except subprocess.TimeoutExpired:
print("命令超时")
# 实时获取输出
process = subprocess.Popen(['ping', '8.8.8.8'],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True)
for line in process.stdout:
print(line.strip()) # 实时打印输出
# 获取完整输出
stdout, stderr = process.communicate(timeout=10)
print(f"完整输出: {stdout}")
os.system(简单但功能有限)
import os
# 执行命令,只返回退出状态码
return_code = os.system('ls -la')
print(f"退出码: {return_code}")
# 无法直接获取输出,但可以重定向
os.system('ls -la > output.txt')
os.popen(旧式方法)
import os
# 读取输出
with os.popen('ls -la') as f:
output = f.read()
print(output)
# 写入命令输入
with os.popen('wc -l', 'w') as f:
f.write('line1\nline2\nline3\n')
高级用法示例
管道命令
import subprocess
# 链式命令(等同于 ls | grep .py)
ps1 = subprocess.Popen(['ls'], stdout=subprocess.PIPE)
ps2 = subprocess.Popen(['grep', '.py'], stdin=ps1.stdout,
stdout=subprocess.PIPE, text=True)
ps1.stdout.close() # 允许ps1在ps2运行时接收SIGPIPE信号
output = ps2.communicate()[0]
print(f"Python文件: {output}")
带环境变量
import subprocess import os env = os.environ.copy() env['MY_VAR'] = 'custom_value' result = subprocess.run(['env'], env=env, capture_output=True, text=True) print(result.stdout)
同时处理stdout和stderr
import subprocess
# 合并stdout和stderr
result = subprocess.run(['ls', '/nonexistent'],
capture_output=True,
text=True,
stderr=subprocess.STDOUT)
print(f"合并的输出: {result.stdout}")
# 分别处理
result = subprocess.run(['ls', '/nonexistent'],
capture_output=True,
text=True)
print(f"stdout: {result.stdout}")
print(f"stderr: {result.stderr}")
安全注意事项
import subprocess
import shlex
# ❌ 危险:直接使用shell=True可能导致注入
user_input = "; rm -rf /"
result = subprocess.run(f"echo {user_input}", shell=True, capture_output=True, text=True)
# ✅ 安全:使用参数列表
result = subprocess.run(['echo', user_input], capture_output=True, text=True)
# ✅ 或者使用shlex.quote
safe_input = shlex.quote(user_input)
result = subprocess.run(f"echo {safe_input}", shell=True, capture_output=True, text=True)
最佳实践建议
- 优先使用subprocess模块,它更安全、功能更强大
- 避免使用 shell=True,除非确实需要shell特性
- 使用参数列表而非字符串,避免注入风险
- 设置合理的timeout,防止命令挂起
- 处理异常,如FileNotFoundError、TimeoutExpired等
import subprocess
def run_command(cmd, timeout=30):
"""安全的命令执行封装"""
try:
result = subprocess.run(
cmd,
capture_output=True,
text=True,
timeout=timeout,
check=True # 非零返回码会抛出CalledProcessError
)
return {
'success': True,
'stdout': result.stdout,
'stderr': result.stderr,
'returncode': result.returncode
}
except subprocess.TimeoutExpired:
return {'success': False, 'error': '命令执行超时'}
except subprocess.CalledProcessError as e:
return {'success': False, 'error': f'命令返回错误码 {e.returncode}', 'output': e.output}
except FileNotFoundError:
return {'success': False, 'error': '命令不存在'}
版权声明:足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播