当前位置: 首页 > 面试题库 >

新手python子进程:“写入错误:管道损坏”

长孙永思
2023-03-14
问题内容

感谢以下有用的建议:

所以当我似乎固定

  1. 将命令分成对Popen的单独调用
  2. stderr = subprocess.PIPE作为每个Popen链的参数。

新代码:

import subprocess
import shlex
import logging

def run_shell_commands(cmds):
    """ Run commands and return output from last call to subprocess.Popen.
        For usage see the test below.
    """
    # split the commands
    cmds = cmds.split("|")
    cmds = list(map(shlex.split,cmds))

    logging.info('%s' % (cmds,))

    # run the commands
    stdout_old = None
    stderr_old = None
    p = []
    for cmd in cmds:
        logging.info('%s' % (cmd,))
        p.append(subprocess.Popen(cmd,stdin=stdout_old,stdout=subprocess.PIPE,stderr=subprocess.PIPE))
        stdout_old = p[-1].stdout
        stderr_old = p[-1].stderr
    return p[-1]


pattern = '"^85567      "'
file = "j"

cmd1 = 'grep %s %s | sort -g -k3 | head -10 | cut -d" " -f2,3' % (pattern, file)
p = run_shell_commands(cmd1)
out = p.communicate()
print(out)

原始帖子:

我花了很长时间尝试解决通过简单的subprocess.Popen传递问题。

码:

import subprocess
cmd = 'cat file | sort -g -k3 | head -20 | cut -f2,3' % (pattern,file)
p = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE)
for line in p.stdout:
    print(line.decode().strip())

输出文件的长度约为1000行:

...
sort: write failed: standard output: Broken pipe
sort: write error

文件长度大于241行的输出:

...
sort: fflush failed: standard output: Broken pipe
sort: write error

文件长度小于241行的输出很好。

我一直在疯狂地阅读文档并进行谷歌搜索,但是我缺少的子流程模块有一些基础知识……也许与缓冲区有关。我试过p.stdout.flush()并使用缓冲区大小和p.wait()。我试图用“
sleep 20; 猫中等文件”,但这似乎没有错误。


问题答案:

从子流程文档的配方中:

# To replace shell pipeline like output=`dmesg | grep hda`
p1 = Popen(["dmesg"], stdout=PIPE)
p2 = Popen(["grep", "hda"], stdin=p1.stdout, stdout=PIPE)
output = p2.communicate()[0]


 类似资料:
  • Process 结构体代表了一个正在运行的子进程,并公开了stdin(标准输入),stdout(标准输出) 和 stderr(标准错误) 句柄,通过管道和底层的进程交互。(原文:The Process struct represents a running child process, and exposes the stdin, stdout and stderr handles for int

  • 上周六,我们开始遇到管道破裂的问题,每天清晨都有一个通过石英调度器运行的作业。下面是一些细节。 该作业由一个本地java类组成,该类调用基于Talend的作业。每个基于Talend的作业都会出现断管错误。奇怪的是,当我运行通过调度程序提交的同一个java类时,不会抛出错误,作业也会成功运行。此外,该作业流在Tomcat中运行。 我应该在Talend jobs中做些什么,看看是否可以先建立连接?正如

  • 我使用vscode与remote-ssh连接我的服务器,配置后,我想连接我的主机,但失败了,对话框显示:“无法建立连接到XX,进程试图写入不存在的管道。” 产出:

  • 问题内容: 我收到了一个调用返回的消息,已将套接字()作为目标传递给了该调用。可以预期的是,远程主机在它们受够了之后会简单地断开连接,而我不会从他们那里收到任何信息。 发生掉线时,出现以下错误: 但是我只有一个接口。我该如何区分折断的管道错误和其他类型的错误? 问题答案: 断开的管道错误在syscall软件包中定义。您可以使用相等运算符将错误与syscall中的错误进行比较。检查http://go

  • 问题内容: 我有一个非常简单的Python 3脚本: 但它总是说: 我在网上看到了解决此问题的所有复杂方法,但是我直接复制了此代码,因此我认为代码有问题,而不是Python的SIGPIPE。 我正在重定向输出,因此,如果上面的脚本被命名为“ open.py”,那么我要运行的命令将是: 问题答案: 我没有重现这个问题,但是也许这种方法可以解决这个问题:(逐行写入而不是使用) 你能抓住破损的管道吗?这

  • 因此,服务器和客户端都发生这种情况。我有来自通道活动方法的通道处理程序上下文,我正在尝试使用写入AndFlush(对象消息)方法向其写入对象,但似乎消息永远不会进入创建的管道。 下面是我的客户端处理程序的样子(我重写了包解码器和编码器中的一些方法来调试) 这是我如何写入ChannelHandlerContext通道变量 当我运行我的代码时,“从客户端写入服务器的数据”是打印机,但“在客户端上编码的