I have a script that gets a wallpaper from Unsplash, then sets it. I setup a flag --repeat
to continuously get images based on a specified interval. The script functions perfectly but to make this happen I used & disown
to detach the process so it stays running in the background
My issue is trying to kill the old process(es) when I run the script again. I used to use kill $(ps -ef | awk '/script_name/{print $2}')
to kill the existing processes. Of course doing this, I can't recommend anyone else use the script.
while read line ; do
case $line in
*-r*) [[ $line =~ $$ ]] || kill `echo $line | cut -d' ' -f2` ;;
esac
done < <(ps -ef | grep -w 'bg.sh')
I was using this at the top of said script but as of today the processes that spawn aren't named by the script's name, so now I can't figure out a way to find them, let alone kill them; Of course causing above snippets to stop working. I've tried just running kill $!
at the top of the script but I must be doing something wrong. All the sources I find online have only confused me more
CodePudding user response:
If you want to kill all already running instances of a certain script, you can add something like this at the top of script;
for pid in $(pidof -x SCRIPT_NAME); do
if [ "$pid" != $$ ]; then
kill "$pid"
fi
done
You can also try using killall
instead of kill
.
killall SCRIPT_NAME
CodePudding user response:
You could store the process id in a .pid
file. When starting the new script, you can let it read that file and kill the old script.
Example:
#!/bin/bash
PIDFILE=/fixed/path/to/script.pid
if [[ -e $PIDFILE ]]; then # check if the .pid file exists
OLDPID=$(<"$PIDFILE")) # read it
while kill "$OLDPID" 2>/dev/null # try to kill it
do
sleep 1 # sleep a little
done
echo "$OLDPID is dead"
fi
# Store the new pid
trap 'rm "$PIDFILE"' EXIT
echo $$ > "$PIDFILE"
# let the script do what it's supposed to do here
You could add a limit to how many times it should try to kill the old script too and do a kill -0 "$OLDPID"
afterwards just to confirm that it's actually dead.