Linux Command to Check If a Shell Script Is Running or Not

Linux command to check if a shell script is running or not

Check this

ps aux | grep "aa.sh"

How to check whether a shell script is running in the server

You have various ways of checking if a program is running.

Checking for a running program with the same name

pidof xyz

This will print the pids of every program named "xyz", and return with exit code 0 if a pid was found and 1 if not (so if you just want to know if the program is running, you just have to check the exit code of that command).

If you don't have pidof:

ps aux | grep xyz.sh | grep -v grep

And check if the output is empty or not.

A more reliable solution

If you want something a bit more sophisticated (that will check if this script is running, and not just something with the same name), the solution is usually to create a pid file:

At the beginning of the script, check if the file /var/run/xyz.pid exists. If it exists, then the program is already running. If not, then create it and continue your normal execution. At the end of the normal execution of the script, remove the file.

You may write the pid of the script as you create the xyz.pid file. That way, if the user wants to stop the running script without killing it themselves, they can call the script again with an option like, for example, --stop. Then your script can read the .pid file and kill it properly (by sending a signal asking it to shut down gracefully for example).

This is the way a lot of services (some http servers for example) work.

How to check if script is running or not from script itself?

You need a proper lock. I'd do using flock like this:

exec 201> /tmp/lock.$(basename $0).file
if ! flock -n 201 ; then
echo "another instance of $0 is running";
exit 1
fi

# cmds

exec 201>&-
rm -rf /tmp/lock.$(basename $0).file

This basically creates lock for script using a temporary file. The temporary file has particular significance other than it's used to tell whether your script has acquired a lock.
When there's an instance of this program running, the next run of the same program can't run as the lock will prevent it.

How to detect if a bash script is already running, considering its arguments


How to detect if a bash script is already running

If you are aware of the drawbacks of your method, using pgrep looks fine. Note that both $0 and $* can have regex-syntax stuff in them, you have to escape them first, and I think I would also do pgrep -f "^$0... to match it from the beginning.

why a "wc -l" on 123976 is returning 2?

Because command substitution $(..) spawns a subshell, so there are two shells running, when pgrep is executed.

Overall, echo $(cmd) is an antipattern. Just run it cmd.

In some cases, like when there is single one command inside command substitution, bash optimizes and replaces (exec) the subshell with the command itself, effectively eliminating the subshell. This is an optimization. That's why processes=$(pgrep ..) returns 1.

Why?

There is one more process running.

script to check script is running and start it, if it’s stopped

You should not need to run the complete bash script again. Changing

./tg/tgcli -s ./bot/bot.lua $@

to

while :; do
./tg/tgcli -s ./bot/bot.lua $@
done

will restart bot.lua everytime it exits.

How can I check if a program exists from a Bash script?


Answer

POSIX compatible:

command -v <the_command>

Example use:

if ! command -v <the_command> &> /dev/null
then
echo "<the_command> could not be found"
exit
fi

For Bash specific environments:

hash <the_command> # For regular commands. Or...
type <the_command> # To check built-ins and keywords

Explanation

Avoid which. Not only is it an external process you're launching for doing very little (meaning builtins like hash, type or command are way cheaper), you can also rely on the builtins to actually do what you want, while the effects of external commands can easily vary from system to system.

Why care?

  • Many operating systems have a which that doesn't even set an exit status, meaning the if which foo won't even work there and will always report that foo exists, even if it doesn't (note that some POSIX shells appear to do this for hash too).
  • Many operating systems make which do custom and evil stuff like change the output or even hook into the package manager.

So, don't use which. Instead use one of these:

command -v foo >/dev/null 2>&1 || { echo >&2 "I require foo but it's not installed.  Aborting."; exit 1; }
type foo >/dev/null 2>&1 || { echo >&2 "I require foo but it's not installed.  Aborting."; exit 1; }
hash foo 2>/dev/null || { echo >&2 "I require foo but it's not installed.  Aborting."; exit 1; }

(Minor side-note: some will suggest 2>&- is the same 2>/dev/null but shorter – this is untrue. 2>&- closes FD 2 which causes an error in the program when it tries to write to stderr, which is very different from successfully writing to it and discarding the output (and dangerous!))

If your hash bang is /bin/sh then you should care about what POSIX says. type and hash's exit codes aren't terribly well defined by POSIX, and hash is seen to exit successfully when the command doesn't exist (haven't seen this with type yet). command's exit status is well defined by POSIX, so that one is probably the safest to use.

If your script uses bash though, POSIX rules don't really matter anymore and both type and hash become perfectly safe to use. type now has a -P to search just the PATH and hash has the side-effect that the command's location will be hashed (for faster lookup next time you use it), which is usually a good thing since you probably check for its existence in order to actually use it.

As a simple example, here's a function that runs gdate if it exists, otherwise date:

gnudate() {
if hash gdate 2>/dev/null; then
gdate "$@"
else
date "$@"
fi
}

Alternative with a complete feature set

You can use scripts-common to reach your need.

To check if something is installed, you can do:

checkBin <the_command> || errorMessage "This tool requires <the_command>. Install it please, and then run this tool again."

How to write a shell script to check the service file is running or not if not then restart the service?

Your grep command fails, and myApp isn't found in the path you give.

Problems/fixes in your script:

  1. Don't put a space between #! and /bin/sh.
  2. You must not have spaces around the = sign when you assign a variable (this causes your grep to fail).
  3. The variable should be quoted in the grep command, in case the name has a space.
  4. Make sure there is a / before and after the path to myApp. It looks like you might have missed the trailing / above.
  5. When grepping for a process (not the best way to check if a process is running), make sure you exclude the grep process itself, otherwise you'll always see some process running and think your service is up.
  6. The parenthesis in while isn't needed, as this isn't C. In sh, it means you run the command true in a subshell.
  7. grep has a parameter -q which makes it output nothing. This is better than redirecting to /dev/null.

Putting it all together:

#!/bin/sh
SERVICE="myApp"

while true
do
if ! ps -ef | grep -v grep | grep -qi "$SERVICE"
then nohup "/full_path/$SERVICE" &
fi
sleep 10
done


Related Topics



Leave a reply



Submit