python - 终止子进程后 Shell 挂起

标签 python subprocess

我知道在 SO 上有很多类似的问题,例如 this onethis one也许还有几个,但它们似乎都不适用于我的特定情况。我对 subprocess.Popen() 的工作原理缺乏了解也无济于事。

我想实现的是:启动一个子进程(一个命令行广播播放器),它也向终端输出数据,也可以接收输入——等待一段时间——终止子进程——退出shell。我在 OSX 10.9 上运行 python 2.7

案例 1. 这会启动广播播放器(但只有音频!),终止进程,退出。

import subprocess
import time

p = subprocess.Popen(['/bin/bash', '-c', 'mplayer http://173.239.76.147:8090'],
                     stdin=subprocess.PIPE, stdout=subprocess.PIPE, shell=False,
                     stderr=subprocess.STDOUT)
time.sleep(5)
p.kill()

案例 2. 这会启动广播播放器,输出广播名称、歌曲、比特率等信息,并接受输入。它终止了子进程,但它从不存在外壳,即使在使用“Ctrl-C”后终端也变得不可用。

p = subprocess.Popen(['/bin/bash', '-c', 'mplayer http://173.239.76.147:8090'],
                     shell=False)
time.sleep(5)
p.kill()

关于如何做的任何想法?我什至在考虑如果没有其他选择的话,是否可以为子进程打开一个 slave-shell (当然这也是我不知道的事情)。谢谢!

最佳答案

似乎 mplayer 使用了 curses 库,当 kill()terminate()出于某种原因,它无法正确清理库状态。

要恢复终端状态,您可以使用reset 命令。

演示:

import subprocess, time

p = subprocess.Popen(['mplayer', 'http://173.239.76.147:8090'])
time.sleep(5)
p.terminate()
p.wait()  # important!

subprocess.Popen(['reset']).wait()

print('Hello, World!')

原则上也应该可以使用 stty sane,但它对我来说效果不佳。


正如 Sebastian 指出的那样,上面的代码(现在已添加)中缺少一个 wait() 调用。使用此 wait() 调用 and 使用 terminate() 终端不会被弄乱(因此不应该有任何需要用于重置)。

如果没有 wait(),我有时会遇到 python 进程和 mplayer 之间混合输出的问题。

此外,正如 Sebastian 所指出的,mplayer 的一个特定解决方案是向 mplayer 的标准输入发送一个 q 以退出

我保留使用 reset 的代码,因为它可以与使用 curses 库的任何程序一起使用,无论它是否正确地拆除了库或不,因此它可能在其他不可能干净退出的情况下很有用。

关于python - 终止子进程后 Shell 挂起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22899568/

相关文章:

Python tkinter - 动态更改标签字体颜色

python - 如何在 tensorflow 中加权剪辑?

python - 项目结构的绝对进口和相对进口

python - 如何在 aws lambda/tmp 目录中运行 python 脚本

python - 如何使用 python subprocess 命令在不同目录中运行 shell 命令?

python - 从另一个 python 文件控制 python 进程

python - 如何创建非持久 Elixir/SQLAlchemy 对象?

python - Tweepy 和 flask : failed to get request token

python - 子进程 python 而不关闭 cmd

python - 如何使用子进程在python中解压gz文件