You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

使用subprocess.run和cat命令合并文件时在Linux环境下出现阻塞问题

使用subprocess.run和cat命令合并文件时在Linux环境下出现阻塞问题

嗨,我来帮你分析下问题出在哪:你的代码之所以在Linux下卡住,核心原因是同时混用了shell=True和拆分后的命令列表,这让shell解析命令的方式完全乱套了!

你看,当设置shell=True时,subprocess会启动一个shell进程,需要把完整的命令字符串传给它,让shell自己去拆分参数、处理重定向。但你现在把命令拆成了列表['cat', '/path/a.txt', '/path/b.txt', '>', '/path/c.txt']再传进去,shell会把这个列表当成:用sh -c 'cat'来执行,剩下的/path/a.txt这些都变成了shell自身的参数,而不是cat的参数。

这时候cat因为没收到任何文件名参数,就会默认等着从标准输入读内容,可你的程序又没给它输入,自然就一直卡住不动了!

接下来给你几个解决办法,按推荐程度排序:

1. 最推荐:直接用Python原生代码合并文件(跨平台+无安全隐患)

完全不用依赖系统的cat命令,Windows和Linux都能跑,还能避免路径里有特殊字符(比如空格、&)时的命令解析错误:

import os
current_dir = os.getcwd()
bottom_file = 'b.txt'
top_file = 'a.txt'
result_file = 'c.txt'

# 用二进制模式处理,兼容文本和二进制文件
with open(os.path.join(current_dir, result_file), 'wb') as out_f:
    # 先写入top_file的内容
    with open(os.path.join(current_dir, top_file), 'rb') as in_f:
        out_f.write(in_f.read())
    # 再追加bottom_file的内容
    with open(os.path.join(current_dir, bottom_file), 'rb') as in_f:
        out_f.write(in_f.read())

2. 修复shell=True的写法

如果你一定要用cat命令,那直接把完整的命令字符串传给subprocess.run,不要拆分:

import os, subprocess
current_dir = os.getcwd()
bottom_file = 'b.txt'
top_file = 'a.txt'
result_file = 'c.txt'

command_line = f"cat {os.path.join(current_dir, top_file)} {os.path.join(current_dir, bottom_file)} > {os.path.join(current_dir, result_file)}"
# 直接传命令字符串,不用split
subprocess.run(command_line, shell=True)

不过要注意:如果你的路径里包含空格、*这类shell特殊字符,这种写法还是会出问题,所以更推荐第一种方法。

3. 不用shell=True的subprocess写法

如果想避免shell=True的安全风险(比如路径被注入恶意命令),可以用subprocess的stdout重定向来实现:

import os, subprocess
current_dir = os.getcwd()
bottom_file = 'b.txt'
top_file = 'a.txt'
result_file = 'c.txt'

with open(os.path.join(current_dir, result_file), 'wb') as out_f:
    # 执行cat top_file,把输出写到结果文件
    subprocess.run(
        ['cat', os.path.join(current_dir, top_file)],
        stdout=out_f
    )
    # 再执行cat bottom_file,追加到结果文件
    subprocess.run(
        ['cat', os.path.join(current_dir, bottom_file)],
        stdout=out_f
    )

这样调整后,程序就不会再阻塞了,而且能稳定合并文本或二进制文件~

备注:内容来源于stack exchange,提问作者paul18fr

火山引擎 最新活动