我正在编写一个使用Unix less(1)在终端上显示文本的程序。以下是相关部分:
less = subprocess.Popen(['less -F -'], stdin=subprocess.PIPE,
stdout=sys.stdout, shell=True)
try:
less.stdin.write(rfc_text)
less.stdin.flush()
less.stdin = sys.stdin
less.wait()
except IOError:
less.terminate()
return errno.EPIPE
except KeyboardInterrupt:
less.terminate()
return 0
在等待较少完成时,我会监听KeyboardInterrupt异常。如果我抓到一个,我用SIGTERM信号减少了,并退出我的程序。
现在,当发生这种情况时,我回到了我的shell提示符,但shell不再回应我写的内容,我必须重置(1)才能使它再次运行。
关于如何在不将我的stdin带入坟墓的情况下减少死亡的任何想法?完整来源可在https://github.com/jforberg/rfc/blob/master/rfc.py
上找到编辑:经过一些实验,我发现默认情况下,less(1)和man(1)都忽略了control-C笔划。所以简单地忽略它可能是一个可行的选择。我不确定我认为这是正确的做法,所以如果有人有建议我仍然非常感兴趣。
答案 0 :(得分:1)
最简单的方法是让用户正确退出less
(按q
):
#!/usr/bin/env python
from subprocess import PIPE, Popen
p = Popen(['less'], stdin=PIPE)
try:
p.communicate(''.join("%d\n" % i for i in range(1000)))
except KeyboardInterrupt:
print("Press `q` to exit.")
p.wait()
答案 1 :(得分:1)
基本上有两种选择:
较少,man和相关程序不会在control-C上终止,它们只会中止他们当前正在进行的任何操作。所以简单地忽略击键似乎是一种选择。这将保留有用的功能,即可以在不终止程序的情况下中止冗长的操作,例如长搜索。程序也可以像类似程序一样运行(在本例中是Unix人)。
Less接受-K选项,使其在control-C上终止,就像大多数非交互式命令一样。
答案 2 :(得分:0)
为了使此过程顺利进行,我提出了以下6行解决方案(基于J.F.Sebastian代码):
logpath = os.path.join(cwd, "filename.log")
less = Popen(["less","+F","-S", logpath])
retcode = None
while retcode is None:
try: retcode = less.wait()
except KeyboardInterrupt: pass
我认为这解决了原作。如果您要输入较少的内容,则可能需要调整所使用的Popen方法:wait()
或communicate(input)
。