Florian Dietz Florian Dietz - 11 days ago 6
AppleScript Question

(re)start python script with applescript

I have a python script that runs in an infinite loop (it's a server).
I want to write an applescript that will start this script if it isn't started yet, and otherwise force-quit and restart it. This will make it easy for me to make changes to the server code while programming.

Currently I only know how to start it: 'do shell script "python server.py"'

Answer

Note that AppleScript's do shell script starts the shell (/bin/sh) in the root directory (/) by default, so you should specify an explicit path to server.py

In the following examples I'll assume path ~/server.

Here's the shell command:

pid=$(pgrep -fx 'python .*/server\.py'); [ "$pid" ] && kill -9 $pid; python ~/server/server.py

As an AppleScript statement, wrapped in do shell script - note the \-escaped inner " and \ chars.:

do shell script "pid=$(pgrep -fx 'python .*/server\\.py'); [ \"$pid\" ] && kill -9 $pid; python ~/server/server.py"
  • pgrep -fx '^python .*/server\.py$' uses pgrep to find your running command by regex against the full command line (-f), requiring a full match (-x), and returns the PID (process ID), if any.

    • Note that I've used a more abstract regex to underscore the fact that pgrep (always) treats its search term as a regular expression.
      To specify the full launch command line as the regex, use python ~/server/server\.py - note the \-escaping of . for full robustness.
  • [ "$pid" ] && kill -9 $pid kills the process, if a PID was found ([ "$pid" ] is short for [ -n "$pid" ] and evaluates to true only if $pid is nonempty); -9 sends signal SIGKILL, which forcefully terminates the process.

  • python ~/server/server.py then (re)starts your server.