5

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.

I have start.sh:

#!/bin/sh script='/path/to/my/script.py' echo 'starting $script with nohup' nohup /usr/bin/python $script & 

and 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. I think that's an appropriate way to find the pid but i wouldn't bet much on it. start.sh successfully starts it. when i run stop.sh, i can no longer find the process by "ps aux | grep 'myscript.py'" but the console outputs:

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

#!/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
  • 1
    You can get the PID of the previous command with $!. Then you can use this in the stop.sh file. You also have nothing in there to deal with starting multiple times and such. Commented Jul 16, 2013 at 20:30

5 Answers 5

4

It is because ps aux |grep SOMETHING also finds the grep SOMETHING process, because SOMETHING matches. After the execution the grep is finished, so it cannot find it.

Add a line: ps aux | grep -v grep | grep YOURSCRIPT

Where -v means exclude. More in man grep.

Sign up to request clarification or add additional context in comments.

Comments

2

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. If changing the script is not an option, have a look at start-stop-daemon.

If you want to continue with the grep-like approach, have a look at proctools. They're built in on most GNU/Linux machines and readily available on BSD including OS X:

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

Comments

2

init-type scripts are useful for this. 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.

#!/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 

Comments

1

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

will return both the pid for the instance of script.py and also for this instance of 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.

Comments

0

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.

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 

Try this out.

1 Comment

@Brad It checks if the file exists. See here.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.