2

I have the following Python script, all seems to work how I want it to, except for the following:

  • less opens with the option -F, this will follow the file like Tail would.
  • to inspect (move through) the file the user has to ctrl + c to send an interrrupt.
  • when sending the ctrl +c (interrupt) this gets send to the python script, which will terminate the less process.

Is there a way to be able to use ctrl +c in the less window and not terminating the script while doing this?

#!/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

Should there not be a nice solution using my current script, maybe someone can advice me a more suitable solution, language does not matter much.

Cheers,

Phillip

SOLUTION:

#!/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!")
fedorqui
  • 275,237
  • 103
  • 548
  • 598
  • open it in a new tab/window taking focus from where the python script is running – Padraic Cunningham Jul 22 '14 at 10:11
  • You should probably be using `subprocess` instead of `os` to launch processes. It makes things such as killing processes much easier – loopbackbee Jul 22 '14 at 10:14
  • Hi, I don't actually want to kill the process, I want to send the interrupt signal to less, not to the Python script – Phillip Parrin Jul 22 '14 at 10:49
  • Padraic Cunningham, do you mean open a new Terminal tab? This is not really an option as users will also be using Putty to start this script, or am I misunderstanding your comment? – Phillip Parrin Jul 22 '14 at 10:50

1 Answers1

1

You can try ignoring the SIGINT signal and remove the -K less option:

#!/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!")

The try...except is no longer useful, so you could probably remove it.

To be honest my recollection of signal handling is a bit foggy, and I'm not 100% sure why this works. Obviously ignoring SIGINT (generated by Ctrl+C) prevents Python acting on the signal, but the spawned process should inherit it parent's signal disposition. Possibly less sets up its own signal handlers, and maybe this is why it works.

mhawke
  • 84,695
  • 9
  • 117
  • 138
  • Hey mhawke, thanks for the reply and the answer, it works like a charm. Much appreciated! I'll edit my question to include the solution you proposed. – Phillip Parrin Jul 22 '14 at 11:23
  • @PhillipParrin Great. Let me know if there are any unexpected side-effects. – mhawke Jul 22 '14 at 11:27
  • Ok will do, at the moment it is doing exactly what I needed. Not closing the spawn less process upon ctrl+c. Again really appreciated! – Phillip Parrin Jul 22 '14 at 11:54