杰瑞科技汇

Python如何调用自身os模块?

os.system vs. subprocess

  • os.system: 这是一个比较老、简单直接的方法,它会启动一个新的shell(在Linux/macOS上是/bin/sh,在Windows上是cmd.exe)来执行你的命令,执行完后,你的Python脚本会继续往下运行。缺点是,它无法获取到被调用脚本的输出结果,也难以进行复杂的错误处理。
  • subprocess: 这是现代Python官方推荐的模块,它提供了更强大、更灵活、更安全的方式来创建子进程,你可以控制输入、输出、错误流,检查返回码,并且可以避免os.system可能带来的shell注入风险。

使用 os.system() (简单但不推荐)

这是最简单的方法,适用于你只是想运行一个脚本,不关心它的输出和返回结果。

Python如何调用自身os模块?-图1
(图片来源网络,侵删)
import os
# 假设你有一个名为 other_script.py 的脚本
script_path = 'other_script.py'
print(f"准备使用 os.system 运行 {script_path}...")
# 返回值是脚本的退出状态码 (0表示成功,非0表示失败)
exit_code = os.system(script_path)
print(f"脚本执行完毕,退出码: {exit_code}")

other_script.py 的内容 (用于测试):

# other_script.py
import time
print("这是另一个Python脚本,它正在运行...")
time.sleep(2)
print("它执行完了!")

如何运行: 将两个文件放在同一个目录下,然后运行主脚本。

python main_script.py

输出:

准备使用 os.system 运行 other_script.py...
这是另一个Python脚本,它正在运行...
它执行完了!
脚本执行完毕,退出码: 0

缺点:

Python如何调用自身os模块?-图2
(图片来源网络,侵删)
  1. 无法获取输出: 你无法在主脚本中捕获other_script.py打印的"这是另一个Python脚本..."
  2. 安全风险: 如果script_path变量来自不可信的输入,可能会被恶意利用(script_path = "malicious_command; rm -rf /")。

使用 subprocess 模块 (强烈推荐)

subprocess是更现代、更强大的选择。

subprocess.run() (最常用,Python 3.5+)

这是subprocess模块的推荐接口,功能全面且易于使用。

场景A:执行一个Python脚本,并捕获其标准输出

import subprocess
script_path = 'other_script.py'
print(f"准备使用 subprocess.run 运行 {script_path}...")
# 使用 check=True 会在脚本返回非0退出码时抛出 CalledProcessError 异常
# text=True 会将输出解码为文本
# capture_output=True 会捕获标准输出和标准错误
try:
    result = subprocess.run(
        ['python', script_path],  # 将命令和参数作为列表传递,更安全
        check=True,
        capture_output=True,
        text=True,
        encoding='utf-8' # 明确指定编码
    )
    # result.stdout 是脚本的输出
    print("脚本执行成功!")
    print("捕获到的标准输出:")
    print(result.stdout)
    # result.stderr 是脚本的标准错误输出
    if result.stderr:
        print("捕获到的标准错误:")
        print(result.stderr)
    # result.returncode 是脚本的退出码
    print(f"退出码: {result.returncode}")
except subprocess.CalledProcessError as e:
    print(f"脚本执行失败,返回码: {e.returncode}")
    print(f"标准输出: {e.stdout}")
    print(f"标准错误: {e.stderr}")

输出:

Python如何调用自身os模块?-图3
(图片来源网络,侵删)
准备使用 subprocess.run 运行 other_script.py...
脚本执行成功!
捕获到的标准输出:
这是另一个Python脚本,它正在运行...
它执行完了!
退出码: 0

场景B:直接执行Python代码字符串

如果你想执行一段Python代码,而不是一个文件,可以使用-c选项。

import subprocess
code_to_run = "print('Hello from inline code!'); import datetime; print(f'Time: {datetime.datetime.now()}')"
print(f"准备执行代码: {code_to_run}")
# 注意命令需要是一个列表
command = ['python', '-c', code_to_run]
result = subprocess.run(command, capture_output=True, text=True, check=True)
print("\n执行结果:")
print(result.stdout)

输出:

准备执行代码: print('Hello from inline code!'); import datetime; print(f'Time: {datetime.datetime.now()}')
执行结果:
Hello from inline code!
Time: 2025-10-27 10:30:00.123456

subprocess.Popen() (更底层,更灵活)

当你需要与子进程进行更复杂的交互时(持续发送输入或实时读取输出),Popen是更好的选择,它不会像run那样等待命令执行完成。

import subprocess
script_path = 'other_script.py'
print("准备使用 subprocess.Popen 运行脚本...")
# 启动进程,但不等待
process = subprocess.Popen(
    ['python', script_path],
    stdout=subprocess.PIPE,  # 捕获标准输出
    stderr=subprocess.PIPE,  # 捕获标准错误
    text=True,
    encoding='utf-8'
)
# 可以在这里做其他事情...
# 等待进程结束,并获取输出
stdout, stderr = process.communicate()
print("\n--- Popen 执行结果 ---")
print("标准输出:")
print(stdout)
if stderr:
    print("标准错误:")
    print(stderr)
print(f"退出码: {process.returncode}")

总结与最佳实践

方法 优点 缺点 适用场景
os.system() 简单、一行代码搞定 无法获取输出、不安全、功能有限 快速执行简单命令,不关心结果
subprocess.run() 强烈推荐、功能强大、安全、可获取输出和错误码、可控制超时 相对os.system代码稍多 绝大多数场景,特别是需要获取脚本输出或进行错误处理时
subprocess.Popen() 最灵活,可进行复杂交互(如实时通信) 代码更复杂,需要手动管理进程生命周期 需要与子进程持续交互,或构建复杂的管道命令时

最终建议:

  1. 永远优先使用 subprocess.run(),它提供了os.system的所有优点,同时弥补了它的所有缺点。
  2. 将命令和参数作为列表传递给subprocess.run['python', 'script.py']),而不是字符串,这样可以有效防止shell注入攻击。
  3. 使用capture_output=Truetext=True来方便地处理文本输出。
  4. 使用check=True来自动处理脚本执行失败的情况,它会为你抛出异常。
  5. 如果只是想运行一个命令且不关心其结果,os.system虽然简单,但为了代码的健壮性和可维护性,仍然推荐使用subprocess.run(..., check=False)
分享:
扫描分享到社交APP
上一篇
下一篇