Python shell 脚本打开 less 并使用 +F 选项

2 投票
1 回答
1049 浏览
提问于 2025-04-18 14:14

我有一个Python脚本,基本上都按照我想要的方式运行,但有几个问题:

  • less命令是用-F选项打开的,这样它就像Tail命令一样,可以实时跟踪文件的变化。
  • 用户想要查看文件内容时,需要按ctrl + c来发送一个中断信号。
  • 当按下ctrl + c(中断信号)时,这个信号会被发送到Python脚本,导致less进程被终止。

有没有办法在less窗口中使用ctrl + c,而不终止脚本呢?

#!/usr/bin/python
import sys
import os
import subprocess as sp
try:
    if(len(sys.argv) < 2):
        print "Choose an EngineID!"
    engineID = sys.argv[1]

    logdir='/data/work/silverlocal-%s/log' % engineID
    logfiles = sorted([ f for f in os.listdir(logdir) if f.startswith('log-%s' % engineID)])
    lastlog = (logdir + "/" + logfiles[-1])

    os.spawnlpe(os.P_WAIT, 'less', 'less', '+F', '-K', (lastlog), os.environ)

except KeyboardInterrupt:
    pass

如果用我现在的脚本没有好的解决办法,也许有人可以给我推荐一个更合适的解决方案,语言方面没有太大限制。

谢谢,

Phillip

解决方案:

#!/usr/bin/python
import sys
import os
import subprocess as sp
import signal

if(len(sys.argv) < 2):
print "Choose an EngineID!"
engineID = sys.argv[1]

logdir='/data/awork/silverlocal-%s/log' % engineID
logfiles = sorted([ f for f in os.listdir(logdir) if f.startswith('log-%s' % engineID)])
lastlog = (logdir + "/" + logfiles[-1])
old_action = signal.signal(signal.SIGINT, signal.SIG_IGN)
os.spawnlpe(os.P_WAIT, 'less', 'less', '+F', (lastlog), os.environ)
signal.signal(signal.SIGINT, old_action)    # restore old signal disposition
print("I'm still running!")

1 个回答

1

你可以试着忽略一下 SIGINT 信号,并去掉 -K 这个 less 的选项:

#!/usr/bin/python
import sys
import os
import signal
import subprocess as sp

try:
    if(len(sys.argv) < 2):
        print "Choose an EngineID!"
    engineID = sys.argv[1]

    logdir='/data/work/silverlocal-%s/log' % engineID
    logfiles = sorted([ f for f in os.listdir(logdir) if f.startswith('log-%s' % engineID)])
    lastlog = (logdir + "/" + logfiles[-1])

    old_action = signal.signal(signal.SIGINT, signal.SIG_IGN)
    os.spawnlpe(os.P_WAIT, 'less', 'less', '+F', (lastlog), os.environ)
    signal.signal(signal.SIGINT, old_action)    # restore old signal disposition
except KeyboardInterrupt:
    pass

print("I'm still running!")

其实 try...except 这部分就没什么用了,所以你可以考虑把它删掉。

老实说,我对信号处理的记忆有点模糊,不太确定为什么这样做有效。显然,忽略 SIGINT(就是按 Ctrl+C 产生的信号)可以让 Python 不去处理这个信号,但被启动的进程应该会继承它父进程的信号设置。可能 less 自己设置了信号处理方式,这也许就是它能正常工作的原因。

撰写回答