2013-07-16 7 views
5

Ich habe ein einfaches Python-Skript, ich muss starten und stoppen, und ich muss ein start.sh und stop.sh-Skript verwenden, um es zu tun.shell start/stop für Python-Skript

Ich habe start.sh:

#!/bin/sh 

script='/path/to/my/script.py' 
echo 'starting $script with nohup' 

nohup /usr/bin/python $script & 

und stop.sh

#!/bin/sh 

PID=$(ps aux | grep "/path/to/my/script.py" | awk '{print $2}') 
echo "killing $PID" 
kill -15 $PID 

Ich bin hauptsächlich mit der stop.sh Skript. I denke, das ist ein geeigneter Weg, um die PID zu finden, aber ich würde nicht viel darauf wetten. start.sh startet es erfolgreich. wenn ich stop.sh laufen, ich kann nicht mehr finden, den Prozess durch "ps aux | grep 'myscript.py'" aber die Konsole Ausgänge:

killing 25052 
25058 
./stop.sh: 5: kill: No such process 

so scheint es, wie es funktioniert und gibt einen Fehler von Sorten mit „keinem solchen Prozess“.

Ist das tatsächlich ein Fehler? Nähme ich mich dem vernünftig? Gibt es noch andere Dinge, auf die ich achten sollte?

EDIT - ich endete eigentlich mit so etwas wie dies oben: start.sh

#!/bin/bash 
ENVT=$1 
COMPONENTS=$2 


TARGETS=("/home/user/project/modules/script1.py" "/home/user/project/modules/script2.py") 
for target in "${TARGETS[@]}" 
do 
     PID=$(ps aux | grep -v grep | grep $target | awk '{print $2}') 
     echo $PID 
     if [[ -z "$PID" ]] 
     then 
       echo "starting $target with nohup for env't: $ENVT" 
       nohup python $target $ENVT $COMPONENTS & 
     fi 
done 

stop.sh

#!/bin/bash 
ENVT=$1 

TARGETS=("/home/user/project/modules/script1.py" "/home/user/project/modules/script2.py") 
for target in "${TARGETS[@]}" 
do 
    pkill -f $target 
    echo "killing process $target" 
done 
+1

Sie können die PID des vorherigen Befehls mit '$!' Erhalten. Dann können Sie dies in der 'stop.sh' Datei verwenden. Du hast auch nichts drin um mit dem Start mehrere Male und so umzugehen. – will

Antwort

4

Es ist, weil ps aux |grep SOMETHING auch den Prozess grep SOMETHING findet, weil etwas Streichhölzer. Nach der Ausführung ist der Grep beendet, so dass er nicht gefunden werden kann.

eine Zeile hinzufügen: ps aux | grep -v grep | grep YOURSCRIPT

Wo -v Mittel ausschließen. Mehr in man grep.

1

ps aux | grep "/path/to/my/script.py"

wird sowohl die pid für die Instanz von script.py als auch für diese Instanz von grep zurückgeben. Das wird wahrscheinlich der Grund sein, warum du keinen solchen Prozess bekommst: bis du den Grep getötet hast, ist er schon tot.

1

Der Ansatz "correct" wäre wahrscheinlich, dass Ihr Skript seine PID in eine Datei in/var/run schreibt und löscht es, wenn Sie das Skript beenden. Wenn das Ändern des Skripts keine Option ist, werfen Sie einen Blick auf start-stop-daemon.

Wenn Sie mit dem grep-ähnlichen Ansatz fortfahren möchten, werfen Sie einen Blick auf proctools. Sie sind gebaut in den meisten GNU/Linux-Rechner und leicht verfügbar auf BSD einschließlich O X:

pkill -f /path/to/my/script.py 
0

Ich habe keinen Unix-Rechner auf im Moment, also kann ich das nicht testen, aber es sollte ziemlich einfach sein, um die Idee zu bekommen.

start.sh:

if [ -e ./temp ] 
then 
    pid=`cat temp` 
    echo "Process already exists; $pid" 
else 
    script='/path/to/my/script.py' 
    echo 'starting $script with nohup' 
    nohup /usr/bin/python $script & 
    echo $! > temp 
fi 

Anschlag.sh:

if [ -e ./temp ] 
then 
    pid=`cat temp` 
    echo "killing $pid" 
    kill -15 $PID 
    rm temp 
else 
    echo "Process not started" 
fi 

Probieren Sie es aus.

+0

@Brad Es prüft, ob die Datei existiert. Siehe [hier] (http://tldp.org/LDP/abs/html/fto.html). – will

2

Init-Typ-Skripte sind dafür nützlich. Dies ist sehr ähnlich zu einem, den ich benutze. Sie speichern die PID in einer Datei, und wenn Sie überprüfen möchten, ob sie läuft, schauen Sie in das/proc-Dateisystem.

#!/bin/bash 

script_home=/path/to/my 
script_name="$script_home/script.py" 
pid_file="$script_home/script.pid" 

# returns a boolean and optionally the pid 
running() { 
    local status=false 
    if [[ -f $pid_file ]]; then 
     # check to see it corresponds to the running script 
     local pid=$(< "$pid_file") 
     local cmdline=/proc/$pid/cmdline 
     # you may need to adjust the regexp in the grep command 
     if [[ -f $cmdline ]] && grep -q "$script_name" $cmdline; then 
      status="true $pid" 
     fi 
    fi 
    echo $status 
} 

start() { 
    echo "starting $script_name" 
    nohup "$script_name" & 
    echo $! > "$pid_file" 
} 

stop() { 
    # `kill -0 pid` returns successfully if the pid is running, but does not 
    # actually kill it. 
    kill -0 $1 && kill $1 
    rm "$pid_file" 
    echo "stopped" 
} 

read running pid < <(running) 

case $1 in 
    start) 
     if $running; then 
      echo "$script_name is already running with PID $pid" 
     else 
      start 
     fi 
     ;; 
    stop) 
     stop $pid 
     ;; 
    restart) 
     stop $pid 
     start 
     ;; 
    status) 
     if $running; then 
      echo "$script_name is running with PID $pid" 
     else 
      echo "$script_name is not running" 
     fi 
     ;; 
    *) echo "usage: $0 <start|stop|restart|status>" 
     exit 
     ;; 
esac