2013-07-16 38 views
5

Tôi có một script python đơn giản tôi cần phải bắt đầu và dừng lại và tôi cần sử dụng một script start.sh và stop.sh để thực hiện nó.shell start/stop cho tập lệnh python

Tôi có start.sh:

#!/bin/sh 

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

nohup /usr/bin/python $script & 

và stop.sh

#!/bin/sh 

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

tôi chủ yếu quan tâm đến kịch bản stop.sh. Tôi nghĩ rằng đó là một cách thích hợp để tìm pid nhưng tôi sẽ không đặt cược nhiều vào nó. start.sh bắt đầu thành công nó. khi tôi chạy stop.sh, tôi không còn có thể tìm thấy quá trình bằng cách "ps aux | grep 'myscript.py'" nhưng kết quả đầu ra giao diện điều khiển:

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

nên nó có vẻ như nó hoạt động và đưa ra một lỗi của các loại với "Không có quá trình như vậy".

Đây có phải là lỗi không? Tôi có đang tiếp cận điều này một cách lành mạnh không? Có những thứ khác mà tôi nên chú ý không?

EDIT - Tôi thực sự đã kết thúc với một cái gì đó như thế này: 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

Bạn có thể lấy PID của lệnh trước đó bằng '$!'. Sau đó, bạn có thể sử dụng tệp này trong tệp 'stop.sh'. Bạn cũng không có gì trong đó để đối phó với việc bắt đầu nhiều lần và như vậy. – will

Trả lời

4

Đó là vì ps aux |grep SOMETHING cũng thấy quá trình grep SOMETHING, vì SOMETHING kết quả phù hợp. Sau khi thực hiện grep được hoàn thành, vì vậy nó không thể tìm thấy nó.

Thêm một dòng: ps aux | grep -v grep | grep YOURSCRIPT

Trường hợp v có nghĩa là loại trừ. Thêm trong số man grep.

1

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

sẽ trả lại cả pid cho cá thể của script.py và cũng cho phiên bản grep này. Đó có thể là lý do tại sao bạn đang nhận được một quá trình không như vậy: bởi thời gian bạn nhận được xung quanh để giết chết grep, nó đã chết.

1

Cách tiếp cận "correct" có thể là để tập lệnh của bạn ghi pid của nó vào một tệp trong/var/run và xóa nó khi bạn giết tập lệnh. Nếu thay đổi tập lệnh không phải là một tùy chọn, hãy xem start-stop-daemon.

Nếu bạn muốn tiếp tục với phương pháp tiếp cận giống như grep, hãy xem proctools. Họ đang xây dựng ở trên hầu hết các máy GNU/Linux và có sẵn trên BSD bao gồm OS X:

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

Tôi không có một hộp unix trên vào lúc này, vì vậy tôi không thể kiểm tra điều này, nhưng nó nên khá đơn giản để có được ý tưởng.

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 

dừng.sh:

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

Hãy thử tính năng này.

+0

@Brad Nó sẽ kiểm tra xem tệp có tồn tại không. Xem [tại đây] (http://tldp.org/LDP/abs/html/fto.html). – will

2

tập lệnh loại init hữu ích cho việc này. Điều này rất giống với cái tôi sử dụng. Bạn lưu trữ pid trong một tệp và khi bạn muốn kiểm tra xem nó có đang chạy hay không, hãy xem xét hệ thống tệp/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 
Các vấn đề liên quan