在第一行之后杀死子进程 [英] Killing subprocess after first line

查看:44
本文介绍了在第一行之后杀死子进程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在执行从 python 连接到外部服务器的程序.
如果用户未通过身份验证,程序会要求输入用户名和密码.

I am executing program which connects to external server from python.
If user is not authenticated, the program asks for username and password.

子程序输出如下所示:

Authentication Required

Enter authorization information for "Web API"

<username_prompt_here>
<password_prompt_here>

我想在打印需要身份验证"后立即终止子进程,但问题是,我的代码运行错误 - 子进程要求提供凭据,在用户提供凭据后,子进程被终止.

I want to kill subprocess right after 'Authentication Required' is printed, but the problem is, that my code works wrong - subprocess is asking for credentials and after user provides it, the subprocess is killed.

这是我的代码:

with subprocess.Popen(self.command, stdout=subprocess.PIPE, shell=True, bufsize=1, universal_newlines=True) as process:
    for line in process.stdout:
        if 'Authentication Required' in line:
            print('No authentication')
            process.kill()
        print(line)

我做错了什么?

推荐答案

我做错了什么?

如果子进程及时刷新其标准输出缓冲区,则您的代码没问题(如果您想在 'Authentication Required' 行之后终止子进程,而不管其位置).请参阅 Python:从 subprocess.communicate() 读取流输入

Your code is ok (if you want to kill the subprocess after 'Authentication Required' line regardless its position) if the child process flushes its stdout buffer in time. See Python: read streaming input from subprocess.communicate()

观察到的行为表明子进程使用块缓冲模式,因此您的父脚本看到 'Authentication Required' 行为时已晚,或者使用 process.kill() 不会杀死它的后代(由命令创建的进程).

The observed behavior indicates that the child uses a block-buffering mode and therefore your parent script sees the 'Authentication Required' line too late or that killing the shell with process.kill() doesn't kill its descendants (processes created by the command).

解决方法:

  • 看看你是否可以传递一个命令行参数,比如 --line-buffered(被 grep 接受),来强制一个行缓冲模式
  • 或者查看 stdbufunbufferscript 实用程序是否适用于您的情况
  • 或者提供一个伪 tty 来欺骗进程,使其认为它直接在终端中运行——它也可能强制使用行缓冲模式.
  • See whether you could pass a command-line argument such as --line-buffered (accepted by grep), to force a line-buffered mode
  • Or see whether stdbuf, unbuffer, script utilities work in your case
  • Or provide a pseudo-tty to hoodwink the process into thinking that it runs in a terminal directly — it may also force the line-buffered mode.

查看代码示例:

而且 - 并不总是我想在第一行之后杀死程序.仅当第一行是需要身份验证"时

And - not always I want to kill program after first line. Only if first line is 'Authentication required'

假设块缓冲问题已修复,如果第一行包含Authentication Required,则终止子进程:

Assuming the block-buffering issue is fixed, to kill the child process if the first line contains Authentication Required:

with Popen(shlex.split(command), 
           stdout=PIPE, bufsize=1, universal_newlines=True) as process:
    first_line = next(process.stdout)
    if 'Authentication Required' in first_line:
        process.kill()
    else: # whatever
        print(first_line, end='')
        for line in process.stdout:
            print(line, end='')

如果 shell=True 在您的情况下是必需的,请参阅如何终止使用 shell 启动的 python 子进程=真.

If shell=True is necessary in your case then see How to terminate a python subprocess launched with shell=True.

这篇关于在第一行之后杀死子进程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆