2013-07-16 134 views
5

我有一個簡單的python腳本,我需要啓動和停止,我需要使用start.sh和stop.sh腳本來完成它。python腳本的shell啓動/停止

我有start.sh:

#!/bin/sh 

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

nohup /usr/bin/python $script & 

和stop.sh

#!/bin/sh 

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

我主要關心的是stop.sh腳本。我認爲這是一個適當的方式來找到PID,但我不會對它下注很多。 start.sh成功啓動它。當我運行stop.sh,我可以不再"ps aux | grep 'myscript.py'"但控制檯輸出發現過程:

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

所以它看起來像它的工作原理並給出了各種各樣的錯誤與「沒有這樣的過程」。

這實際上是一個錯誤?我是否以一種理智的方式接近這一點?還有其他的事情我應該關注嗎?

編輯 - 其實,我結束了這樣的事情: 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

你可以用'$!'獲得前一個命令的PID。然後你可以在'stop.sh'文件中使用它。你也沒有什麼可以處理多次開始等等。 – will

回答

4

這是因爲ps aux |grep SOMETHING還發現了grep SOMETHING過程,因爲有些東西火柴。執行完成後,grep完成,因此找不到它。

添加一行:ps aux | grep -v grep | grep YOURSCRIPT

凡-v手段排除。更多信息請參見man grep

1

ps aux | grep「/path/to/my/script.py」

將返回script.py實例的pid和grep的這個實例。這可能就是爲什麼你沒有這樣的過程:到你殺死grep的時候,它已經死了。

1

"correct"方法可能會讓您的腳本將其pid寫入/ var/run中的文件,並在您終止腳本時將其清除。如果不能更改腳本,請參閱start-stop-daemon

如果您想繼續使用類似grep的方法,請參閱proctools。他們建在大多數GNU/Linux機器和容易獲得的BSD包括OS X:

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

我沒有Unix機器上的那一刻,所以我不能對此進行測試,但它應該相當簡單的想法。

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 

停止。sh:

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

試試看。

+0

@Brad它檢查文件是否存在。參見[這裏](http://tldp.org/LDP/abs/html/fto.html)。 – will

2

init類型的腳本對此很有用。這與我使用的非常相似。您將pid存儲在一個文件中,當您想檢查它是否正在運行時,請查看/ 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