【问题标题】:shell start / stop for python scriptpython脚本的shell启动/停止
【发布时间】:2013-07-16 20:27:58
【问题描述】:

我有一个简单的 python 脚本,我需要启动和停止,我需要使用 start.sh 和 stop.sh 脚本来完成它。

我有 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

所以它似乎有效并且给出了“没有这样的过程”的各种错误。

这真的是一个错误吗?我是否以理智的方式处理这个问题?还有其他我应该注意的事情吗?

EDIT - 实际上我最终得到了这样的结果: 开始.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

【问题讨论】:

  • 可以通过$!获取上一条命令的PID。然后你可以在stop.sh 文件中使用它。你也没有什么可以处理多次启动等问题。

标签: python linux shell


【解决方案1】:

这是因为ps aux |grep SOMETHING 也找到了grep SOMETHING 进程,因为SOMETHING 匹配。执行后grep完成,所以找不到它。

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

其中 -v 表示排除。 man grep 中的更多内容。

【讨论】:

    【解决方案2】:

    "correct" 方法可能是让您的脚本将其 pid 写入 /var/run 中的文件,并在您终止脚本时将其清除。如果无法更改脚本,请查看start-stop-daemon

    如果您想继续使用类似grep 的方法,请查看proctools。它们内置在大多数 GNU/Linux 机器上,并且可以在包括 OS X 在内的 BSD 上轻松使用:

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

    【讨论】:

      【解决方案3】:

      init-type 脚本对此很有用。这与我使用的非常相似。您将 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
      

      【讨论】:

        【解决方案4】:

        ps 辅助 | grep "/path/to/my/script.py"

        将返回 script.py 实例和 grep 实例的 pid。这可能就是你没有这样的过程的原因:当你开始杀死 grep 时,它已经死了。

        【讨论】:

          【解决方案5】:

          我目前没有 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
          

          stop.sh:

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

          试试这个。

          【讨论】:

          • @Brad 检查文件是否存在。见here
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-09-05
          • 1970-01-01
          相关资源
          最近更新 更多