shell script execution check if it is already running or not

匿名 (未验证) 提交于 2019-12-03 01:55:01

问题:

GNU bash, version 1.14.7(1)

I have a script is called "abc.sh" I have to check this from abc.sh script only... inside it I have written following statement

status=`ps -efww | grep -w "abc.sh" | grep -v grep | grep -v $$ | awk '{ print $2 }'` if [ ! -z "$status" ]; then         echo "[`date`] : abc.sh : Process is already running"         exit 1; fi 

I know it's wrong because every time it exits as it found its own process in 'ps' how to solve it? how can I check that script is already running or not from that script only ?

回答1:

An easier way to check for a process already executing is the pidof command.

if pidof -x "abc.sh" >/dev/null; then     echo "Process already running" fi 

Alternatively, have your script create a PID file when it executes. It's then a simple exercise of checking for the presence of the PID file to determine if the process is already running.

#!/bin/bash # abc.sh  mypidfile=/var/run/abc.sh.pid  # Could add check for existence of mypidfile here if interlock is # needed in the shell script itself.  # Ensure PID file is removed on program exit. trap "rm -f -- '$mypidfile'" EXIT  # Create a file with current PID to indicate that process is running. echo $$ > "$mypidfile"  ... 

Update: The question has now changed to check from the script itself. In this case, we would expect to always see at least one abc.sh running. If there is more than one abc.sh, then we know that process is still running. I'd still suggest use of the pidof command which would return 2 PIDs if the process was already running. You could use grep to filter out the current PID, loop in the shell or even revert to just counting PIDs with wc to detect multiple processes.

Here's an example:

#!/bin/bash  for pid in $(pidof -x abc.sh); do     if [ $pid != $$ ]; then         echo "[$(date)] : abc.sh : Process is already running with PID $pid"         exit 1     fi done 


回答2:

I you want the "pidof" method, here is the trick:

    if pidof -o %PPID -x "abc.sh">/dev/null; then         echo "Process already running"     fi 

Where the -o %PPID parameter tells to omit the pid of the calling shell or shell script. More info in the pidof man page.



回答3:

Here's one trick you'll see in various places:

status=`ps -efww | grep -w "[a]bc.sh" | awk -vpid=$$ '$2 != pid { print $2 }'` if [ ! -z "$status" ]; then     echo "[`date`] : abc.sh : Process is already running"     exit 1; fi 

The brackets around the [a] (or pick a different letter) prevent grep from finding itself. This makes the grep -v grep bit unnecessary. I also removed the grep -v $$ and fixed the awk part to accomplish the same thing.



回答4:

Someone please shoot me down if I'm wrong here

I understand that the mkdir operation is atomic, so you could create a lock directory

#!/bin/sh lockdir=/tmp/AXgqg0lsoeykp9L9NZjIuaqvu7ANILL4foeqzpJcTs3YkwtiJ0 mkdir $lockdir  || {     echo "lock directory exists. exiting"     exit 1 } # take pains to remove lock directory when script terminates trap "rmdir $lockdir" EXIT INT KILL TERM  # rest of script here 


回答5:

Use the PS command in a little different way to ignore child process as well:

ps -eaf | grep -v grep | grep $PROCESS | grep -v $$ 


回答6:

I create a temporary file during execution.

This is how I do it:

#!/bin/sh # check if lock file exists if [ -e /tmp/script.lock ]; then   echo "script is already running" else # create a lock file   touch /tmp/script.lock   echo "run script..." #remove lock file  rm /tmp/script.lock fi 


回答7:

Here's how I do it in a bash script:

if ps ax | grep $0 | grep -v $$ | grep bash | grep -v grep then     echo "The script is already running."     exit 1 fi 

This allows me to use this snippet for any bash script. I needed to grep bash because when using with cron, it creates another process that executes it using /bin/sh.



回答8:

I have found that using backticks to capture command output into a variable, adversly, yeilds one too many ps aux results, e.g. for a single running instance of abc.sh:

ps aux | grep -w "abc.sh" | grep -v grep | wc -l 

returns "1". However,

count=`ps aux | grep -w "abc.sh" | grep -v grep | wc -l` echo $count 

returns "2"

Seems like using the backtick construction somehow temporarily creates another process. Could be the reason why the topicstarter could not make this work. Just need to decrement the $count var.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!