[英]shell start / stop for python script
I have a simple python script i need to start and stop and i need to use a start.sh and stop.sh script to do it. 我有一个简单的python脚本,我需要启动和停止,我需要使用start.sh和stop.sh脚本来完成它。
I have start.sh: 我有start.sh:
#!/bin/sh
script='/path/to/my/script.py'
echo 'starting $script with nohup'
nohup /usr/bin/python $script &
and stop.sh 和stop.sh
#!/bin/sh
PID=$(ps aux | grep "/path/to/my/script.py" | awk '{print $2}')
echo "killing $PID"
kill -15 $PID
I'm mainly concerned with the stop.sh script. 我主要关注的是stop.sh脚本。 I think that's an appropriate way to find the pid but i wouldn't bet much on it. 我认为这是寻找pid的合适方式,但我不会对它下注太多。 start.sh successfully starts it. start.sh成功启动它。 when i run stop.sh, i can no longer find the process by "ps aux | grep 'myscript.py'"
but the console outputs: 当我运行stop.sh时,我再也找不到"ps aux | grep 'myscript.py'"
但控制台输出:
killing 25052
25058
./stop.sh: 5: kill: No such process
so it seems like it works AND gives an error of sorts with "No such process". 所以它似乎工作并给出了“没有这样的过程”的错误。
Is this actually an error? 这实际上是一个错误吗? Am I approaching this in a sane way? 我是否以理智的方式接近这个? Are there other things I should be paying attention to? 还有其他我应该注意的事情吗?
EDIT - I actually ended up with something like this: start.sh 编辑 - 我实际上最终得到了这样的东西: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 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
It is because ps aux |grep SOMETHING
also finds the grep SOMETHING
process, because SOMETHING matches. 这是因为ps aux |grep SOMETHING
也找到了grep SOMETHING
过程,因为SOMETHING匹配。 After the execution the grep is finished, so it cannot find it. 执行完grep后,无法找到它。
Add a line: ps aux | grep -v grep | grep YOURSCRIPT
添加一行: ps aux | grep -v grep | grep YOURSCRIPT
ps aux | grep -v grep | grep YOURSCRIPT
Where -v means exclude. 其中-v表示排除。 More in man grep
. 更多关于man grep
。
init-type scripts are useful for this. init-type脚本对此很有用。 This is very similar to one I use. 这与我使用的非常相似。 You store the pid in a file, and when you want to check if it's running, look into the /proc filesystem. 将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
ps aux | ps aux | grep "/path/to/my/script.py" grep“/path/to/my/script.py”
will return both the pid for the instance of script.py and also for this instance of grep. 将返回script.py实例的pid以及grep的这个实例。 That'll probably be why you're getting a no such process: by the time you get around to killing the grep, it's already dead. 这可能就是为什么你没有这样的过程:当你开始杀死grep时,它已经死了。
The "correct" approach would probably be to have your script write its pid to a file in /var/run, and clear it out when you kill the script. “正确”的方法可能是让您的脚本将其pid写入/ var / run中的文件,并在您终止脚本时清除它。 If changing the script is not an option, have a look at start-stop-daemon . 如果不能选择更改脚本,请查看start-stop-daemon 。
If you want to continue with the grep
-like approach, have a look at proctools . 如果你想继续使用grep
like方法,请查看proctools 。 They're built in on most GNU/Linux machines and readily available on BSD including OS X: 它们内置于大多数GNU / Linux机器上,并且可以在包括OS X在内的BSD上使用:
pkill -f /path/to/my/script.py
I don't have a unix box on at the moment, so i can't test this, but it should be fairly simple to get the idea. 我目前没有打开unix盒子,所以我无法测试这个,但是想到这个想法应该相当简单。
start.sh: 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: stop.sh:
if [ -e ./temp ]
then
pid=`cat temp`
echo "killing $pid"
kill -15 $PID
rm temp
else
echo "Process not started"
fi
Try this out. 试试吧。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.