Python中执行外部程序或系统命令的方法

Python中执行外部程序或系统命令的方法

技术背景

在Python编程中,有时需要调用外部程序或执行系统命令,以实现与操作系统的交互。例如,在脚本中执行文件操作命令、运行其他程序等。Python提供了多种方式来实现这一需求,每种方式都有其特点和适用场景。

实现步骤

1. 使用subprocess.run

subprocess.run是Python 3.5及以上版本推荐的执行外部命令的方式。它返回一个CompletedProcess对象,包含命令的执行结果。

1
2
3
4
5
6
7
8
import subprocess

# 执行ls -l命令
result = subprocess.run(["ls", "-l"], capture_output=True, text=True)
if result.returncode == 0:
print(result.stdout)
else:
print(result.stderr)

2. 使用os.system

os.system可以将命令和参数传递给系统的shell,但它存在安全风险,且不能方便地获取命令的输出。

1
2
3
4
import os

# 执行ls -l命令
os.system("ls -l")

3. 使用subprocess.Popen

subprocess.Popen是一个更底层的接口,提供了更多的控制选项,可用于处理复杂的任务,如管道操作。

1
2
3
4
5
6
7
8
9
import subprocess

# 执行ls -l命令,并获取输出
p = subprocess.Popen(["ls", "-l"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = p.communicate()
if p.returncode == 0:
print(out.decode())
else:
print(err.decode())

4. 使用subprocess.check_output

subprocess.check_output用于获取命令的输出,如果命令执行失败,会抛出CalledProcessError异常。

1
2
3
4
5
6
7
8
import subprocess

try:
# 执行ls -l命令并获取输出
output = subprocess.check_output(["ls", "-l"])
print(output.decode())
except subprocess.CalledProcessError as e:
print(e.stderr.decode())

核心代码

以下是一个综合示例,展示了如何使用subprocess.runshlex.split来执行命令:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import subprocess
import shlex

# 定义命令字符串
command = "python --version"
# 使用shlex.split解析命令
args = shlex.split(command)
# 执行命令
completed_process = subprocess.run(args, capture_output=True, text=True)

if completed_process.returncode == 0:
print("命令执行成功,输出如下:")
print(completed_process.stdout)
else:
print("命令执行失败,错误信息如下:")
print(completed_process.stderr)

最佳实践

  • 优先使用subprocess.run:对于大多数简单的命令执行任务,subprocess.run是首选方法,它提供了简洁的接口和丰富的选项。
  • 避免使用shell=True:如果命令中包含用户输入或不可信的内容,使用shell=True可能会导致安全风险。尽量将命令参数以列表形式传递。
  • 处理命令输出:根据需要使用capture_output=True来捕获命令的标准输出和错误输出,并进行相应的处理。

常见问题

1. FileNotFoundError

错误信息:FileNotFoundError: [Errno 2] No such file or directory: 'ls -a': 'ls -a'
原因:在不使用shell=True的情况下,subprocess期望接收一个命令列表,而不是一个字符串。
解决方法:将命令字符串转换为列表,或者使用shlex.split来解析命令字符串。

1
2
3
4
5
import subprocess
import shlex

# 使用shlex.split解析命令
subprocess.run(shlex.split("ls -a"))

2. TypeError

错误信息:TypeError: [...] NoneType [...]TypeError: a bytes-like object is required, not [...]
原因:未正确设置capture_outputtext参数。
解决方法:确保在需要捕获输出时设置capture_output=True,并在需要将输出转换为字符串时设置text=True

1
2
3
4
5
import subprocess

# 捕获输出并转换为字符串
result = subprocess.run(["ls", "-a"], capture_output=True, text=True)
print(result.stdout)

3. subprocess.CalledProcessError

错误信息:subprocess.CalledProcessError: Command '[...]' returned non-zero exit status 1.
原因:命令执行失败,返回了非零的退出状态码。
解决方法:检查命令的正确性,或者在调用subprocess.run时设置check=False来避免抛出异常。

1
2
3
4
5
6
7
import subprocess

try:
# 执行命令并检查返回码
subprocess.run(["invalid_command"], check=True)
except subprocess.CalledProcessError as e:
print(f"命令执行失败:{e}")

Python中执行外部程序或系统命令的方法
https://119291.xyz/posts/2025-04-16.python-execute-system-command-guide/
作者
ww
发布于
2025年4月16日
许可协议