2013-07-16 18 views
5

Mam prosty skrypt python, muszę zacząć i zatrzymać i potrzebuję użyć skryptu start.sh i stop.sh, aby to zrobić.Powłoki start/stop dla skryptu Pythona

mam start.sh:

#!/bin/sh 

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

nohup /usr/bin/python $script & 

i stop.sh

#!/bin/sh 

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

Martwię się głównie ze skryptem stop.sh. I think to odpowiedni sposób na znalezienie pid, ale nie postawiłbym na niego zbyt wiele. start.sh pomyślnie go uruchamia. gdy uruchamiam stop.sh, już nie mogę znaleźć proces "ps aux | grep 'myscript.py'" ale wyjść na konsole:

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

więc wydaje się, że to działa i daje błąd sortuje z „Nie ma takiego procesu”.

Czy to w rzeczywistości błąd? Czy podchodzę do tego w rozsądny sposób? Czy są inne rzeczy, na które powinienem zwrócić uwagę?

EDIT - I rzeczywiście skończyło się coś takiego: 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

Możesz uzyskać PID poprzedniego polecenia za pomocą '$!'. Następnie możesz użyć tego w pliku 'stop.sh'. Nie macie też nic do czynienia z zaczynaniem wiele razy i takimi. – will

Odpowiedz

4

To dlatego ps aux |grep SOMETHING znajdzie również proces grep SOMETHING, bo coś mecze. Po wykonaniu grep jest zakończony, więc nie może go znaleźć.

Dodaj linię: ps aux | grep -v grep | grep YOURSCRIPT

Gdzie -V środki wykluczyć. Więcej w man grep.

1

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

zwróci zarówno pid dla instancji script.py, jak i dla tego wystąpienia grep. Prawdopodobnie dlatego nie dostaniesz takiego procesu: zanim zdążysz zabić grep, jest już martwy.

1

Podejście "correct" prawdopodobnie spowodowałoby, że twój skrypt zapisze pid do pliku w/var/run i usunie go po zabiciu skryptu. Jeśli zmiana skryptu nie jest możliwa, spójrz na start-stop-daemon.

Jeśli chcesz kontynuować podejście podobne do grep, spójrz na numer proctools. Są one zbudowane w większości maszyn na GNU/Linux i łatwo dostępny na BSD tym OS X:

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

nie mam pole unix w tej chwili, więc nie mogę tego sprawdzić, ale to powinno być dość proste, aby uzyskać ten pomysł.

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 

przystanek.sh:

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

Wypróbuj to.

+0

@Brad Sprawdza, czy plik istnieje. Zobacz [tutaj] (http://tldp.org/LDP/abs/html/fto.html). – will

2

skrypty typu init są przydatne do tego. Jest to bardzo podobne do tego, którego używam. Przechowujesz pid w pliku, a gdy chcesz sprawdzić, czy jest on uruchomiony, zajrzyj do systemu plików/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 
Powiązane problemy