Check if a process is running and if not, restart it using Cron - bash

I have created restart.sh with followin code
#!/bin/bash
ps -aux | grep sidekiq > /dev/null
if [ $? -eq 0 ]; then
echo "Process is running."
else
echo "Process is not running."
fi
To check if sidekiq process is running or not. I will put this script in cron to run daily so if sidekiq is not running, it will start automatically.
My problem is, with
ps -aux | grep sidekiq
even when the process is not running, it shows
myname 27906 0.0 0.0 10432 668 pts/0 S+ 22:48 0:00 grep --color=auto sidekiq
instead of nothing. This gets counted in grep hence even when the process is not running, it shows as "sidekiq" process is running. How to not count this result ? I believe I have to use awk but I am not sure how to use it here for better filtering.

To exclude the grep result from the ps output. Do
ps -aux | grep -v grep | grep sidekiq
(or) do a regEx search of the process name, i.e. s followed by rest of the process name.
ps -aux | grep [s]idekiq
To avoid such conflicts in the search use process grep pgrep directly with the process name
pgrep sidekiq
An efficient way to use pgrep would be something like below.
if pgrep sidekiq >/dev/null
then
echo "Process is running."
else
echo "Process is not running."
fi

Related

Bash - start multiple services if any is running CentOS 6.8

I want to check if one, (or all) services are running, if yes, stop it
#!/bin/bash
# Define an array of processes to be checked.
# If properly quoted, these may contain spaces
check_process=( "nagios" "httpd" )
for p in "${check_process[#]}"; do
if pgrep "$p" > /dev/null; then
echo "Process \`$p' is running, stopping it"
service $p stop
else
echo "Process \`$p' is not running"
fi
done
For httpd service all works fine, script detects correctly httpd service state.
I have issues detecting nagios service state.
But although nagios service is not running, script shows it's running
Process `nagios' is running, stopping it
Stopping nagios:No lock file found in /usr/local/nagios/var/nagios.lock
Process `httpd' is not running
Is there any more elegant way of detecting if nagios service is running without checking if nagios.lock file exists ?
pgrep nagios shows no output when service is not tunning.
I gave up, this works fine for me:
although ps -ef | grep -v grep | grep $service | wc -l shows 0 for nagios, script reports that nagios service is running
#!/bin/bash
logfile=/tmp/stop_nagios.txt
exec >> $logfile
exec 2>&1
service=httpd
if (( $(ps -ef | grep -v grep | grep $service | wc -l) > 0 ))
then
echo "$service is running, stopping it"
date
sudo service $service stop
else
echo "$service is not running"
fi
# check nagios service
FILE=/usr/local/nagios/var/nagios.lock
if test -f "$FILE"; then
echo "nagios service is running, stopping it"
date
sudo service nagios stop
else
echo "nagios is not running..."
fi

how stopped script while procces id exist? Solaris

I want to stall the execution of my script until a process is closed (I have the PID stored in a variable).
#!/bin/bash
outputl=$( ps -ef | grep $var4 | awk '{print $2}' ) >> $logfile
while [ "ps -p $outputl" ] > /dev/null;
do
sleep 1;
done
echo "Stopped $instance" >> $logfile
//command...
It stays in the "while" and not continue whit script.
This line:
while [ "ps -p $output1" ]
does not execute the ps command. It simply tests whether the string "ps -p $output1" is not empty, and it obviously isn't. To test the output of a command, use $():
while [ "$(ps -p "$output1")" ]
But since ps produces a header, this will always be true. The best way to test if a PID exists is to use the kill command with signal 0; this doesn't actually send a signal, it just tests whether it's possible to send a signal. I'm assuming this code is being run either by root or the userid running the application being checked. So you can write:
while kill -0 "$output1" 2>/dev/null
Also, your code for getting the PID into $output1 is wrong. ps -ef will also include the grep command, which matches the name you're looking for, so you need to filter that out. Use:
output1=$(ps -ef | grep "$var4" | awk '!/grep/ { print $2 }')
Redirecting the output to $logfile is not necessary, since variable assignments don't print anything.
Many systems have a pgrep command, which can be used by itself to test if a process with a given name exists; if you have this, you can use it instead of reinventing the wheel (and if not, you should be able to install it).
If you have the PID then just wait for it to complete. Try:
outputl=$( ps -ef | awk -v v="$var4" '$0~v{print $2}' )
wait "$outputl"
echo "Stopped $instance" >> $logfile
then look for a better way to find the pid in the first line.

Script to restart another script

Hello I am trying to write a script to restart other script from command line.
usage should be:
restart someotherscript.sh
cat restart
#!/bin/bash
for pids in $(ps -ef | grep $1 | grep -v grep | awk '{print $2}')
do
kill -9 $pids
done
echo test
sleep 10
$1 &
output is:
root#xxxx:/scripts# restart pricealert.sh
Killed
root#xxxx:
My restart script is killing itself.
What is wrong here? Can you please help me?
Your script is finding itself in the search results because the command you used to start the script contains the script name you're trying to kill.
You can add an if statement to fix this ($$ is the pid of the running script):
if [ "$$" != "$pids" ]; then
kill -9 $pids
fi

find and kill process in ksh script (linux) not working

I have been trying to find and kill any stale process left after the stop in a ksh script on a linux machine and it doesnt seem to work. It works from the command line but in the script though
here is the code
echo "kill any process still running"
ps -ef | grep qpasa |grep -v grep | awk '{print $2}' |xargs kill
and here is the output from the script log
usage: kill [ -s signal | -p ] [ -a ] pid ...
kill -l [ signal ]
can you you please let me know what am I doing wrong here
I think you call the script when no processes are running. Try kill without arguments and you get the same message.
You can redirect the error to /dev/null but I would try something else:
ps -ef | grep qpasa |grep -v grep | awk '{print $2}' | while read pid; do
echo "Killing ${pid}"
kill ${pid}
sleep 2
kill -9 ${pid} 2>/dev/null
done
The first kill gives qpasa the possibility to the stop controlled: Flush caches and close handles. Give qpasa 2 seconds for it.
When qpasa ignores the signal, kill it the hard way. Of course the process could have stopped already, so this time we want to ignore error messages.
When you have a lot of qpasa processes, you want to sleep 2 seconds only once.
First loop through all processes with a friendly kill, wait 5 seconds, and than hard kill the processes you find. When you make a function kill_qpasa_signal for the looping (and using $1 as kill signal), you can use
kill_qpasa_signal 15
sleep 5
kill_qpasa_signal 9

Gracefully shutting down sidekiq processes

Does anyone know how to find sidekiq's pidfile to gracefully shut it down?
Running ps ax | grep sidekiq and then running sidekiqctl stop <pid from grep> consistently gives a no such pidfile error?
Cntl-C and Cntl-D also seem to have no effect.
Closing the process window and reopening a new window doesn't kill the process as it appears to be running as a daemon.
The only consistent fix I've found is rebooting.
Use this to kill sidekiq forcefully.
ps -ef | grep sidekiq | grep -v grep | awk '{print $2}' | xargs kill -9
Sidekiq provides the ability to specify a pidfile at start time or, as shown below, to create the pidfile after the process has been started. In either case you can then use the pidfile at stop time.
Use ps -ef | grep sidekiq to find the pid
Create a file (e.g., sidekiq.pid) with the only contents being the pid you just found
sidekiqctl stop <pidfile_name>
Use -P <pidfile_name> or --pidfile <pidfile_name> when starting sidekiq in the future
Just been looking into this one myself...
Seems like newer versions of Sidekiq have this built in:
https://github.com/mperham/sidekiq/wiki/Signals
kill -USR1 [PROCESS_ID]
Worked great for me. The workers stopped picking up new jobs, but finished the ones they were on, then I finally killed the process when it was done.
kill -TERM [PROCESS_ID]
I've written a little handler that can start or stop sidekiq.
start_stop_sidekiq.sh
#!/bin/bash
cmd=$1
PROJECT_DIR=$2
PIDFILE=$PROJECT_DIR/tmp/pids/sidekiq.pid
cd $PROJECT_DIR
start_function(){
LOGFILE=$PROJECT_DIR/log/sidekiq.log
echo "Starting sidekiq..."
bundle exec sidekiq -d -L $LOGFILE -P $PIDFILE -q mailer,5 -q default -e production
}
stop_function(){
if [ ! -f $PIDFILE ]; then
ps -ef | grep sidekiq | grep busy | grep -v grep | awk '{print $2}' > $PIDFILE
fi
bundle exec sidekiqctl stop $PIDFILE
}
case "$cmd" in
start)
start_function
;;
stop)
stop_function
;;
restart)
stop_function && start_function;
;;
*)
echo $"Usage: $0 {start|stop|restart} /path/to/rails/app"
esac
Save it, type chmod +x start_stop_sidekiq.sh.
Then just run it with:
bash start_stop_sidekiq.sh start /path/to/your/rails/app
or
bash start_stop_sidekiq.sh stop /path/to/your/rails/app
If you only have one Rails app, you can also set the $PROJECT_DIR variable statically so that you don't need to specify the path each time. Hope this helps!
Try using god to monitor sidekiq.
Then all you need to do is bundle exec god stop
Alternatively, you can use:
sidekiqctl stop 60
If you like bashes...
scripts/stop_sidekiq.sh
#!/bin/bash
DIR="$( cd "$( dirname "$0" )" && pwd )"
PROJECT_DIR=$DIR/../ # EDIT HERE: rel path to your project form this file location (my scripts are in ./scripts/)
SIDEKIQ_PID_FILE=$PROJECT_DIR/tmp/pids/sidekiq.pid # EDIT HERE: pid file location
if [ ! -f $SIDEKIQ_PID_FILE ]; then
# if no pid file, retrieve pid and create file
ps -ef | grep sidekiq | grep busy | grep -v grep | awk '{print $2}' > $SIDEKIQ_PID_FILE
fi
(cd $PROJECT_DIR && bundle exec sidekiqctl stop $SIDEKIQ_PID_FILE)
Notes:
will work even if sidekiq started without pid file argument
assumes this script is in a folder inside the project and pid files are stored in ./tmp/pids/
Sharing a bash script that checks if sidekiq is running, sends it TSTP to ask it to not pick up any new jobs, waits until any running jobs are finished and then stops the process by sending a TERM signal to it.
https://gist.github.com/kamilbednarz/5ea6398af2a7537aa8feb5a63f3acf2f

Resources