-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
  • 9,449
  • 21
  • 87
  • 142
Sebastien D
  • 4,369
  • 4
  • 18
  • 46

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.

ChrisGPT was on strike
  • 127,765
  • 105
  • 273
  • 257