python控制linux命令反馈

from flask import Flask,request
import subprocess

app = Flask(__name__)

@app.route('/')
def hello_world():
  return 'Hello, World!'

@app.route('/run', methods=['POST'])
def run_command():
    data = request.get_json()
    command = data.get('command', '')
    
    process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    output, error = process.communicate()
    return output.decode('utf-8')
    
if __name__ == '__main__':
  app.run(host='0.0.0.0', port=5000)

subprocess 模块是 Python 中用于创建和管理子进程的标准库,提供了多种执行外部命令的方法。以下是这些方法的详细对比和使用场景:

1. subprocess.call()

  • 功能:执行命令并等待其完成,返回命令的退出状态码(整数)。
  • 参数:与 check_call() 基本相同。
  • 返回值:命令的退出状态码(0 表示成功,非零表示失败)。
  • 异常:不抛出异常,无论命令是否执行成功。

示例

returncode = subprocess.call(["ls", "-l"])
print(f"命令返回码: {returncode}")

2. subprocess.check_call()

  • 功能:执行命令并等待其完成,若命令返回非零状态码,则抛出异常。
  • 参数:与 call() 相同。
  • 返回值:成功时返回 0。
  • 异常:命令执行失败时抛出 subprocess.CalledProcessError

示例

try:
    subprocess.check_call(["ls", "nonexistent_file"])
except subprocess.CalledProcessError as e:
    print(f"命令失败,返回码: {e.returncode}")

3. subprocess.check_output()

  • 功能:执行命令并捕获其标准输出,若命令失败则抛出异常。
  • 参数:支持 stdinstderrshell 等参数(见上一条回答)。
  • 返回值:命令的标准输出(字节或字符串,取决于 encoding 参数)。
  • 异常:失败时抛出 subprocess.CalledProcessError,包含 returncodeoutput

示例

try:
    output = subprocess.check_output(["ls", "-l"], encoding="utf-8")
    print(output)
except subprocess.CalledProcessError as e:
    print(f"错误: {e.output}")

4. subprocess.Popen

  • 功能:创建一个新的子进程,提供更底层的进程控制(非阻塞执行)。
  • 参数:与其他方法类似,但更灵活,支持更多选项(如 bufsizeenv)。
  • 返回值Popen 对象,用于与子进程交互。
  • 特点
    • 非阻塞:调用后立即返回,不会等待命令执行完成。
    • 可控制输入/输出流,支持异步通信。

示例

# 执行命令并获取标准输出流
process = subprocess.Popen(["ls", "-l"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)

# 异步读取输出
stdout, stderr = process.communicate()  # 等待命令完成并获取输出

print(f"标准输出:\n{stdout.decode('utf-8')}")
print(f"错误输出:\n{stderr.decode('utf-8')}")
print(f"返回码: {process.returncode}")

方法对比表

方法是否阻塞异常处理返回值适用场景
call()不抛出异常退出状态码简单执行命令,不关心输出
check_call()失败时抛出异常0(成功)需确保命令成功执行
check_output()失败时抛出异常标准输出内容获取命令输出并验证执行结果
Popen需手动处理Popen 对象复杂场景(如异步执行、实时交互)

进阶用法:实时读取输出

Popen 可用于实时读取命令输出,适合长时间运行的进程:

process = subprocess.Popen(["ping", "google.com"], stdout=subprocess.PIPE, text=True)

for line in iter(process.stdout.readline, ''):
    print(f"实时输出: {line.strip()}")

process.wait()  # 等待进程结束

安全建议

  1. 避免 shell=True:尤其是处理用户输入时,防止命令注入攻击。
  2. 优先使用列表参数["ls", "-l"]"ls -l" 更安全。
  3. 设置超时:对可能长时间运行的命令使用 timeout 参数。

选择指南

  • 简单执行:用 call()check_call()
  • 获取输出:用 check_output()
  • 复杂控制(异步、实时交互):用 Popen

在 Python 3.5+ 中,subprocess.run() 可替代大部分场景,它是一个更通用的接口,返回 CompletedProcess 对象,包含所有执行结果信息。

是的,在 Python 3.5 之前,subprocess.run() 方法尚未引入,而是使用 subprocess.call()subprocess.check_call()subprocess.check_output() 等方法。下面我将提供一个兼容老版本 Python 的实现:

在linux中会出现cd没命了不适用的情况

因为subprocess.Popen是用子程序调用的情况来改变的
当执行完退出子程序时会改变更改之前的目录
所以没有用而且会报错

可以用os.chdir改变工作目录 亲测可以用

import subprocess
process = subprocess.Popen(['ls'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
output, error = process.communicate()
print(output.decode('utf-8'))

new_dir = "/opt"
os.chdir(new_dir)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值