Florian Dietz
Florian Dietz

Reputation: 997

(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"

Upvotes: 1

Views: 216

Answers (2)

mklement0
mklement0

Reputation: 437428

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 directory path ~/srv.

Here's the shell command:

pid=$(pgrep -fx 'python .*/server\.py'); [ "$pid" ] && kill -9 $pid; python ~/srv/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 ~/srv/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 ~/srv/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 ~/srv/server.py then (re)starts your server.

Upvotes: 1

inspectorG4dget
inspectorG4dget

Reputation: 113925

On the shell, if you do ps aux | grep python\ server.py | head -n1, you'll get the ID of the process running server.py. You can then use kill -9 to kill that process and restart it:

kill -9 `ps aux | grep python\ server.py | head -n1 | python -c 'import sys; print(sys.stdin.read().split()[1])'`

That'll kill it. Al you have to do now is to restart it:

python server.py

You can combine the two with &&:

kill -9 `ps aux | grep python\ server.py | head -n1 | python -c 'import sys; print(sys.stdin.read().split()[1])'` && python server.py

Of course, you already know how to put that in a do shell script!

Upvotes: 1

Related Questions