2013-07-16 1 views
5

J'ai un simple script python que je dois démarrer et arrêter et j'ai besoin d'utiliser un script start.sh et stop.sh pour le faire.démarrage/arrêt du shell pour le script python

J'ai start.sh:

#!/bin/sh 

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

nohup /usr/bin/python $script & 

et stop.sh

#!/bin/sh 

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

Je suis surtout préoccupé par le script stop.sh. Je pense c'est une manière appropriée de trouver le pid mais je ne parierais pas beaucoup dessus. start.sh le démarre avec succès. quand je lance stop.sh, je ne trouve plus le processus par "ps aux | grep 'myscript.py'" mais les sorties de la console:

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

donc il semble que cela fonctionne et donne une erreur de toutes sortes avec « Pas ce processus ».

Est-ce réellement une erreur? Est-ce que j'approche cela d'une manière saine? Y a-t-il d'autres choses sur lesquelles je devrais porter attention?

EDIT - En fait, je fini avec quelque chose comme ceci: 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

Vous pouvez obtenir le PID de la commande précédente avec '$!'. Ensuite, vous pouvez l'utiliser dans le fichier 'stop.sh'. Vous n'avez également rien à faire pour commencer plusieurs fois et ainsi de suite. – will

Répondre

4

Il est parce que ps aux |grep SOMETHING trouve aussi le processus grep SOMETHING, parce que quelque chose allumettes. Après l'exécution, le grep est terminé, donc il ne peut pas le trouver.

Ajouter une ligne: ps aux | grep -v grep | grep YOURSCRIPT

Où -v moyens excluent. Plus dans man grep.

1

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

retournera à la fois le pid pour l'instance de script.py et aussi pour cette instance de grep. Ce sera probablement la raison pour laquelle vous n'obtiendrez pas un tel processus: au moment où vous finissez par tuer le grep, il est déjà mort.

1

L'approche "correct" serait probablement d'avoir votre script écrire son pid dans un fichier dans/var/run, et de l'effacer quand vous avez tué le script. Si le changement de script n'est pas une option, jetez un oeil à start-stop-daemon. Si vous souhaitez continuer avec l'approche grep, regardez proctools. Ils sont construits dans la plupart des machines GNU/Linux et BSD facilement disponible sur OS X, y compris:

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

Je n'ai pas une boîte unix en ce moment, donc je ne peux tester, mais il devrait être assez simple pour avoir l'idée.

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 

arrêt.sh:

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

Essayez-le.

+0

@Brad Vérifie si le fichier existe. Voir [ici] (http://tldp.org/LDP/abs/html/fto.html). – will

2

Les scripts de type init sont utiles pour cela. Ceci est très similaire à celui que j'utilise. Vous stockez le pid dans un fichier, et lorsque vous voulez vérifier s'il est en cours d'exécution, regardez dans le système de fichiers/proc.

#!/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