在第一行之后杀死子进程
Killing subprocess after first line
我正在执行从 python.
连接到外部服务器的程序
如果用户未通过身份验证,程序会要求输入用户名和密码。
这是子程序输出的样子:
Authentication Required
Enter authorization information for "Web API"
<username_prompt_here>
<password_prompt_here>
我想在打印 'Authentication Required' 后立即终止子进程,但问题是,我的代码运行错误 - 子进程要求凭据,在用户提供凭据后,子进程被终止。
这是我的代码:
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)
我做错了什么?
What am I doing wrong?
如果子进程及时刷新其标准输出缓冲区,您的代码就可以了(如果您想在 'Authentication Required'
行之后终止子进程,而不管其位置如何)。参见 Python: read streaming input from subprocess.communicate()
观察到的行为表明子进程使用块缓冲模式,因此您的父脚本看到 'Authentication Required'
行太晚了,或者用 process.kill()
杀死 shell 并没有t kill它的后代(命令创建的进程)。
解决方法:
- 查看是否可以传递命令行参数,例如
--line-buffered
(被 grep
接受),以强制使用行缓冲模式
- 或者查看
stdbuf
、unbuffer
、script
实用程序是否适用于您的情况
- 或者提供一个伪 tty 来欺骗进程,使其认为它直接在终端中运行——它也可能会强制使用行缓冲模式。
参见以下代码示例:
- Python subprocess readlines() hangs
- Python C program subprocess hangs at "for line in iter"
- Last unbuffered line can't be read
And - not always I want to kill program after first line. Only if first line is 'Authentication required'
假设块缓冲问题已解决,如果第一行包含 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
,请参阅 How to terminate a python subprocess launched with shell=True。
我正在执行从 python.
连接到外部服务器的程序
如果用户未通过身份验证,程序会要求输入用户名和密码。
这是子程序输出的样子:
Authentication Required
Enter authorization information for "Web API"
<username_prompt_here>
<password_prompt_here>
我想在打印 'Authentication Required' 后立即终止子进程,但问题是,我的代码运行错误 - 子进程要求凭据,在用户提供凭据后,子进程被终止。
这是我的代码:
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)
我做错了什么?
What am I doing wrong?
如果子进程及时刷新其标准输出缓冲区,您的代码就可以了(如果您想在 'Authentication Required'
行之后终止子进程,而不管其位置如何)。参见 Python: read streaming input from subprocess.communicate()
观察到的行为表明子进程使用块缓冲模式,因此您的父脚本看到 'Authentication Required'
行太晚了,或者用 process.kill()
杀死 shell 并没有t kill它的后代(命令创建的进程)。
解决方法:
- 查看是否可以传递命令行参数,例如
--line-buffered
(被grep
接受),以强制使用行缓冲模式 - 或者查看
stdbuf
、unbuffer
、script
实用程序是否适用于您的情况 - 或者提供一个伪 tty 来欺骗进程,使其认为它直接在终端中运行——它也可能会强制使用行缓冲模式。
参见以下代码示例:
- Python subprocess readlines() hangs
- Python C program subprocess hangs at "for line in iter"
- Last unbuffered line can't be read
And - not always I want to kill program after first line. Only if first line is 'Authentication required'
假设块缓冲问题已解决,如果第一行包含 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
,请参阅 How to terminate a python subprocess launched with shell=True。