ai
  • index
  • cursor
  • vector
  • crawl
  • crawl-front
  • DrissionPage
  • logging
  • mysql
  • pprint
  • sqlalchemy
  • contextmanager
  • dotenv
  • Flask
  • python
  • job
  • pdfplumber
  • python-docx
  • redbook
  • douyin
  • ffmpeg
  • json
  • numpy
  • opencv-python
  • pypinyin
  • re
  • requests
  • subprocess
  • time
  • uuid
  • watermark
  • milvus
  • pymilvus
  • search
  • Blueprint
  • flash
  • Jinja2
  • secure_filename
  • url_for
  • Werkzeug
  • chroma
  • HNSW
  • pillow
  • pandas
  • beautifulsoup4
  • langchain-community
  • langchain-core
  • langchain
  • langchain_unstructured
  • libreoffice
  • lxml
  • openpyxl
  • pymupdf
  • python-pptx
  • RAGFlow
  • tabulate
  • sentence_transformers
  • jsonl
  • collections
  • jieba
  • rag_optimize
  • rag
  • rank_bm25
  • Hugging_Face
  • modelscope
  • all-MiniLM-L6-v2
  • ollama
  • rag_measure
  • ragas
  • ASGI
  • FastAPI
  • FastChat
  • Jupyter
  • PyTorch
  • serper
  • uvicorn
  • markdownify
  • NormalizedLevenshtein
  • raq-action
  • CrossEncoder
  • Bi-Encoder
  • neo4j
  • neo4j4python
  • matplotlib
  • Plotly
  • Streamlit
  • py2neo
  • abc
  • read_csv
  • neo4jinstall
  • APOC
  • neo4jproject
  • uv
  • GDS
  • heapq
  • 基本用法
    • 1. 运行简单命令
    • 2. 替代旧的模块方法
  • 主要函数
    • subprocess.run()
    • subprocess.Popen()
  • 常见用法示例
    • 1. 捕获命令输出
    • 2. 检查命令是否成功
    • 3. 使用管道
    • 4. 设置超时
    • 5. 使用 shell 特性
    • 6. 设置环境变量
  • 安全注意事项
  • 高级特性
    • 1. 实时处理输出
    • 2. 同时处理 stdout 和 stderr
    • 3. 交互式进程
  • 总结

subprocess 模块是 Python 中用于创建和管理子进程的标准库模块,它允许你启动新的应用程序、连接到它们的输入/输出/错误管道,并获取它们的返回码。

基本用法 #

1. 运行简单命令 #

最简单的用法是使用 subprocess.run() 函数:

import subprocess

# 运行简单命令
result = subprocess.run(['ls', '-l'], capture_output=True, text=True)
print(result.stdout)

2. 替代旧的模块方法 #

subprocess 模块旨在替代以下旧模块和函数:

  • os.system()
  • os.spawn*()
  • os.popen()
  • popen2.*()
  • commands.*()

主要函数 #

subprocess.run() #

最常用的高级接口,Python 3.5+ 推荐使用:

result = subprocess.run(
    args,                  # 命令字符串或列表
    *, 
    stdin=None,            # 标准输入
    input=None,            # 传递给子进程的数据
    stdout=None,           # 标准输出处理
    stderr=None,           # 标准错误处理
    capture_output=False,  # 是否捕获输出
    shell=False,           # 是否通过shell执行
    cwd=None,              # 工作目录
    timeout=None,          # 超时时间
    check=False,           # 如果非零退出码是否抛出异常
    text=None,             # 是否以文本模式处理输入输出
    encoding=None,         # 编码
    errors=None            # 编码错误处理方式
)

subprocess.Popen() #

更底层的接口,提供更多控制:

proc = subprocess.Popen(
    args,
    bufsize=-1,
    executable=None,
    stdin=None,
    stdout=None,
    stderr=None,
    preexec_fn=None,
    close_fds=True,
    shell=False,
    cwd=None,
    env=None,
    universal_newlines=None,
    startupinfo=None,
    creationflags=0,
    restore_signals=True,
    start_new_session=False,
    pass_fds=(),
    *,
    group=None,
    extra_groups=None,
    user=None,
    umask=-1,
    encoding=None,
    errors=None,
    text=None
)

常见用法示例 #

1. 捕获命令输出 #

result = subprocess.run(['echo', 'Hello World'], capture_output=True, text=True)
print(result.stdout)  # 输出: Hello World\n

2. 检查命令是否成功 #

try:
    subprocess.run(['false'], check=True)
except subprocess.CalledProcessError as e:
    print(f"命令失败,返回码: {e.returncode}")

3. 使用管道 #

# 将前一个命令的输出作为下一个命令的输入
p1 = subprocess.Popen(['ls', '-l'], stdout=subprocess.PIPE)
p2 = subprocess.Popen(['grep', 'py'], stdin=p1.stdout, stdout=subprocess.PIPE)
p1.stdout.close()  # 允许p1收到SIGPIPE如果p2退出
output = p2.communicate()[0]
print(output.decode('utf-8'))

4. 设置超时 #

try:
    subprocess.run(['sleep', '10'], timeout=5)
except subprocess.TimeoutExpired:
    print("命令执行超时")

5. 使用 shell 特性 #

# 使用shell执行复杂命令
subprocess.run('ls -l | grep py', shell=True)

6. 设置环境变量 #

env = {'PATH': '/usr/local/bin:' + os.environ['PATH']}
subprocess.run(['my_command'], env=env)

安全注意事项 #

  1. 避免使用 shell=True:除非必要,否则应避免使用,因为它可能存在 shell 注入风险。

    # 不安全
    subprocess.run(f'ls {user_input}', shell=True)
    
    # 更安全的方式
    subprocess.run(['ls', user_input])
  2. 正确处理输入:当处理用户输入时,应始终进行适当的清理和验证。

高级特性 #

1. 实时处理输出 #

proc = subprocess.Popen(['ping', 'google.com'], stdout=subprocess.PIPE)
while True:
    line = proc.stdout.readline()
    if not line:
        break
    print(line.decode('utf-8').strip())

2. 同时处理 stdout 和 stderr #

proc = subprocess.Popen(['command'],
                       stdout=subprocess.PIPE,
                       stderr=subprocess.PIPE,
                       text=True)
stdout, stderr = proc.communicate()

3. 交互式进程 #

proc = subprocess.Popen(['python'],
                       stdin=subprocess.PIPE,
                       stdout=subprocess.PIPE,
                       text=True)
proc.stdin.write("print('Hello')\n")
proc.stdin.flush()
output = proc.stdout.readline()
print(output)  # 输出: Hello

总结 #

subprocess 模块提供了强大而灵活的方式来与系统命令和外部程序交互。对于大多数用例,subprocess.run() 是首选的高级接口,而 Popen 则提供了更底层的控制。始终注意安全性,特别是在处理用户输入时。

访问验证

请输入访问令牌

Token不正确,请重新输入