-1

I'm looking for a way to gracefully exit from a long running python script which I launch from my Laravel app.

My actual process to do so is:

  • From Laravel set a 'script_state' to 1 in a MySql table database
  • Launch the python script via shell_exec
  • The python scripts periodically check the 'script_state' by a MySql query. If it is changed to 0 (intentionally from my Laravel app) then it gracefully exit the script

Retrieving the pid from the shell_exec and then kill could have been an option but I actually wan't the script to stop and exit gracefully.

My actual config works but I'm looking for a better approach.

Roman Pokrovskij
  • 8,849
  • 17
  • 82
  • 136
Sebastien D
  • 4,181
  • 4
  • 16
  • 43

1 Answers1

1

Retrieving the pid from the shell_exec and then kill could have been an option but I actually wan't the script to stop and exit gracefully.

This is probably your best bet. You can use SIGTERM to politely ask the script to exit:

The SIGTERM signal is a generic signal used to cause program termination. Unlike SIGKILL, this signal can be blocked, handled, and ignored. It is the normal way to politely ask a program to terminate.

This is effectively what happens when you click the close button in a GUI application.

In your Python code you can handle SIGTERM using the signal module with whatever cleanup logic you want, then exit:

import signal, os

def handler(signum, frame):
    print('Signal handler called with signal', signum)
    raise OSError("Couldn't open device!")

# Set the signal handler and a 5-second alarm
signal.signal(signal.SIGALRM, handler)
signal.alarm(5)

# This open() may hang indefinitely
fd = os.open('/dev/ttyS0', os.O_RDWR)

signal.alarm(0)          # Disable the alarm

See also this Stack Overflow answer for a class that cleans up before exiting.

Chris
  • 112,704
  • 77
  • 249
  • 231