当没有附加控制台时,python 子进程似乎无法正常工作

Posted

技术标签:

【中文标题】当没有附加控制台时,python 子进程似乎无法正常工作【英文标题】:python subprocess doesn't seem to work properly when there's no console attached 【发布时间】:2018-02-04 12:06:28 【问题描述】:

我一直在尝试制作我自己的 Discord 机器人来执行任意代码,我对结果非常满意。但是,似乎每当机器人在没有附加控制台的情况下从任何地方启动(即 Systemd 单元、cron ......)时,行为都是出乎意料的,并且无法正确获取输入或输出。但是,如果它是从 ssh 或计算机本身启动的,则不会发生这种情况。

经过反复试验,我最终假设这一定是由 subprocess 如何处理 stdout 和 stderr 引起的,但我不确定发生了什么。这是处理子进程生成的代码部分。

def_subprocess(path_to_executable)

    timeout_flag = True
    run_process = subprocess.Popen(path_to_executable, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    try:
        stdout, stderr = run_process.communicate(timeout=5)
    except subprocess.TimeoutExpired:
        stdout, stderr, timeout_flag = timeout(run_process)

    return stdout.decode("utf-8"), stderr.decode("utf-8"), timeout_flag




def timeout(process):
    line_number = 0
    stderr = b""
    stdout = b""
    while line_number < 5:
        stdout += process.stdout.readline()
        line_number += 1
    process.kill()
    timeout_flag = True
    return stdout, stderr, timeout_flag

似乎没有标准输出或标准错误,而是感觉它不等待进程完成而只是输出垃圾(给机器人相同的输入并不能保证相同的输出,因为你可以在这张图片中看到:)

我对此感到困惑,我不知道会发生什么。

【问题讨论】:

discord.py 建立在asyncio 之上,您的代码是否在不应该阻塞的时候阻塞?您是否在启动机器人的控制台中收到错误/输出?机器人产生的任何 python 错误都将在那里输出。 这就是帕特里克的问题,当它从控制台启动时,不会发生这种行为。相反,我得到了一切正常的预期行为。当它没有连接控制台时它不起作用,发生这种情况时我无法检查输出。 抱歉,我忘了提你@PatrickHaugh。 这很奇怪。 path_to_executable 使用什么样的值? @PatrickHaugh here's the source code。如果不好,我深表歉意,这是我的第一个“体面”项目之一。 【参考方案1】:

虽然不是真正的解决方案,但我通过使用 screen 作为 systemd 和我的机器人之间的中介找到了一个不错的解决方法。 Systemd 在启动时启动屏幕,屏幕处理我的机器人而不出现任何问题。我会坚持下去的。

【讨论】:

以上是关于当没有附加控制台时,python 子进程似乎无法正常工作的主要内容,如果未能解决你的问题,请参考以下文章

[APUE]进程控制(中)

无法在 Mac 上创建带有子进程的新控制台

调试期间在 Visual Studio 中自动附加到子进程

为啥字符和正斜杠被附加到我的 NSURL?

Node.js 调试 - 无法附加调试器子进程

远程调试,附加到尚未启动的进程