python执行cmd命令,如果cmd命令需要执行的时间过长,该如何停止cmd命令

66 阅读1分钟

python执行cmd命令,如果cmd命令需要执行的时间过长,该如何停止cmd命令

错误示范1

采用timeout

import subprocess
import time


print(time.time(), "Start")

try:
    # 尝试运行一个10秒超时的命令,但subprocess.run设置的超时为5秒
    result = subprocess.run(
        "ping 127.0.0.1 -n 5",  # 命令
        timeout=2,  # 超时时间为5秒
        shell=True,  # 使用shell
        capture_output=True,  # 捕获输出
        encoding="utf-8",  # 输出编码为utf-8
        errors="ignore"  # 忽略编码错误
    )
    # 打印subprocess.run返回结果的更多属性
    print("returncode:", result.returncode)
    print("stdout:", result.stdout)
    print("stderr:", result.stderr)
except subprocess.TimeoutExpired as e:
    # 如果超时异常发生,捕获并打印
    print(time.time(), f"{e}")
print(time.time(),"Finished")
1721034553.5638528 Start
1721034557.6882634 Command 'ping 127.0.0.1 -n 5' timed out after 2 seconds
1721034557.6892624 Finished

错误示范2

import subprocess
import threading
import time

cmd = "ping 127.0.0.1 -n 5"
timeout = 2

print(time.time(), "Start")
process = subprocess.Popen(cmd, shell=True, encoding="utf-8", errors="ignore", stdout=subprocess.PIPE,
                           stderr=subprocess.PIPE)


def target():
    try:
        res = process.communicate()
        print(time.time(), str(res))

    except subprocess.TimeoutExpired:
        process.kill()
        process.communicate()


thread = threading.Thread(target=target)
thread.start()
thread.join(timeout)

print(time.time(), "Finished")
1721034424.2916722 Start
1721034426.3292587 Finished
1721034428.4036288 ('\n Ping 127.0.0.1  32 ֽڵ:\n 127.0.0.1 Ļظ: ֽ=32 ʱ<1ms TTL=128\n 127.0.0.1 Ļظ: ֽ=32 ʱ<1ms TTL=128\n 127.0.0.1 Ļظ: ֽ=32 ʱ<1ms TTL=128\n 127.0.0.1 Ļظ: ֽ=32 ʱ<1ms TTL=128\n 127.0.0.1 Ļظ: ֽ=32 ʱ<1ms TTL=128\n\n127.0.0.1  Ping ͳϢ:\n    ݰ: ѷ = 5ѽ = 5ʧ = 0 (0% ʧ)\nг̵Ĺʱ(ԺΪλ):\n     = 0ms\uece4 = 0msƽ = 0ms\n', '')

超时并不会自动停止执行命令

正确方法

手动停止

process = subprocess.Popen(cmd, shell=True, encoding="utf-8", errors="ignore", stdout=subprocess.PIPE,
                           stderr=subprocess.PIPE)

def target():
    try:
        res = process.communicate()
        print(res)
    except subprocess.TimeoutExpired:
        process.kill()
        process.communicate()

thread = threading.Thread(target=target)
thread.start()
thread.join(timeout)
if thread.is_alive():
    print(f"Terminating {cmd}")
    process.terminate()
    thread.join()