Check whether a process is running or not Linux - linux

Here is my code:
#!/bin/bash
ps cax | grep testing > /dev/null
while [ 1 ]
do
if [ $? -eq 0 ]; then
echo "Process is running."
sleep 10
else
nohup ./testing.sh &
sleep 10
fi
done
I run it as nohup ./script.sh &
and it said nohup: failed to run command './script.sh': No such file or directory
What is wrong?

The file script.sh simply does not exist in the directory that you are issuing the command from.
If it did exist and was not executable you would get:
`nohup: failed to run command ‘./script.sh’: Permission denied

For each newly created scripts on Linux, you should first change the permission as you can see the permission details by using
ls -lah
The following content may help you:
#!/bin/bash
while [ 1 ];
do
date=`date`
pid=`ps -ef | grep "your process" | grep -v grep | awk -F' ' '{print $2}'`
if [[ -n $pid ]]; then
echo "$date - processID $pid is running."
else
echo "$date - the process is not running"
# script to restart your process
say: start the process
fi
sleep 5m
done

Make sure your script is saved as script.sh
and your executing nohup ./script.sh & from the same directory in which script.sh.
Also you can give executable permission for script.sh by
chmod 776 script.sh
or
nohup ./script.sh &
Run as
nohup sh ./script.sh &

Related

How can I restart a process If any exception occured in previous running process file(nohup.out) using shell script?

I have one Jar file in SERVICE_PATH directory.Currently it is running .Suppose any exception or below exception occurred,then i need to kill the current process ,delete the nohup.out file from the directory & then restart the same jar.
Below is my sample code.using below code some time it is working but sometime it is not working.
I will schedule my autoRestart.sh file in crontab.
What is the best way to do this?
#! /bin/sh
SERVICE_PATH=/app/application/DataAdapter
STOPPED_MESSAGE="java.net.UnknownHostException"
File='/app/application/DataAdapter/nohup.out'
chmod a+x "$File"
processId=$(ps -ef | grep 'dataAdapter' | grep -v 'grep' | awk '{ printf $2 }')
echo "$processId"
if [ $processId -eq $(ps -ef | grep 'dataAdapter' | grep -v 'grep' | awk '{ printf $2 }')]
then
if grep -Fxq "$STOPPED" "$File"
then
echo "Process Id New---$processId"
kill -9 $processId
rm -rf $File
nohup java -jar dataAdapter.jar &
else
#nohup java -jar dataAdapter.jar &
echo "Msg if not found"
echo "Process Id New---$processId"
fi
else
kill -9 $processId
rm -rf $File
nohup java -jar dataAdapter.jar &
echo "processId not found"
fi
echo "Task Finished"
echo $$

Background rsync and pid from a shell script

I have a shell script that does a backup. I set this script in a cron but the problem is that the backup is heavy so it is possible to execute a second rsync before the first ends up.
I thought to launch rsync in a script and then get PID and write a file that script checks if the process exist or not (if this file exist or not).
If I put rsync in background I get the PID but I don't know how to know when rsync ends up but, if I set rsync (no background) I can't get PID before the process finish so I can't write a file whit PID.
I don't know what is the best way to "have rsync control" and know when it finish.
My script
#!/bin/bash
pidfile="/home/${USER}/.rsync_repository"
if [ -f $pidfile ];
then
echo "PID file exists " $(date +"%Y-%m-%d %H:%M:%S")
else
rsync -zrt --delete-before /repository/ /mnt/backup/repositorio/ < /dev/null &
echo $$ > $pidfile
# If I uncomment this 'rm' and rsync is running in background, the file is deleted so I can't "control" when rsync finish
# rm $pidfile
fi
Can anybody help me?!
Thanks in advance !! :)
# check to make sure script isn't still running
# if it's still running then exit this script
sScriptName="$(basename $0)"
if [ $(pidof -x ${sScriptName}| wc -w) -gt 2 ]; then
exit
fi
pidof finds the pid of a process
-x tells it to look for scripts too
${sScriptName} is just the name of the script...you can hardcode this
wc -w returns the word count by words
-gt 2 no more than one instance running (instance plus 1 for the pidof check)
if more than one instance running then exit script
Let me know if this works for you.
Test both for presence of pid file and status of the running process like this:
#!/bin/bash
pidfile="/home/${USER}/.rsync_repository"
is_running =0
if [ -f $pidfile ];
then
echo "PID file exists " $(date +"%Y-%m-%d %H:%M:%S")
previous_pid=`cat $pidfile`
is_running=`ps -ef | grep $previous_pid | wc -l`
fi
if [ $is_running -gt 0 ];
then
echo "Previous process didn't quit yet"
else
rsync -zrt --delete-before /repository/ /mnt/backup/repositorio/ < /dev/null &
echo $$ > $pidfile
fi
Hope this helps!!!

Run jar file as Daemon on Linux Ubuntu

I want to install a bot to my Teamspeak3 and run this bot as a daemon on startup. I wrote my own script and copied it to init.d and then added it with update-rc.d to defaults.
#!/bin/sh
#
# JTS3ServerBot Script
#
USER="ts"
NAME="jts3"
DIR="/home/ts/jts3/"
case $1 in
start)
echo "Starting ${NAME} ..."
if [ ! -f $DIR/pid ]; then
sudo -u $USER -c nohup java -jar $DIR/JTS3ServerMod.jar $DIR 2>> /dev/null >> /dev/null &
echo $! > $DIR/pid
echo "${NAME} started ..."
else
echo "${NAME} is already running ..."
fi
;;
stop)
if [ -f $DIR/pid ]; then
PID=$(cat $DIR/pid);
echo "Stopping ${NAME} ..."
kill $PID;
echo "${NAME} stopped ..."
rm $DIR/pid
else
echo "${NAME} is not running ..."
fi
;;
restart)
if [ -f $DIR/pid ]; then
PID=$(cat $DIR/pid);
echo "Stopping ${NAME} ...";
kill $PID;
echo "${NAME} stopped ...";
rm $DIR/pid
echo "Starting ${NAME} ..."
sudo -u $USER -c nohup java -jar $DIR/JTS3ServerMod.jar $DIR 2>> /dev/null >> /dev/null &
echo $! > $DIR/pid
echo "${NAME} started ..."
else
echo "${NAME} is not running ..."
fi
;;
esac
A pid file in generated, but if i try to kill the process with this pid i get an error that the process does not exist. If i use top there is no process with the pid listed.
root#vps-1023645-8462:~# service jts3 start
Starting jts3 ...
jts3 started ...
root#vps-1023645-8462:~# cat /home/ts/jts3/pid
10206
root#vps-1023645-8462:~# kill 10206
bash: kill: (10206) - No such process
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1762 ts 20 0 1881m 14m 3408 S 0 1.4 215:47.28 ts3server_linux
32356 ts 20 0 164m 1576 1336 S 0 0.2 0:09.85 tsdnsserver_lin
I have found another solution for my problem. I use upstart (works only with Ubuntu) to run my jar-File as a daemon. Upstart manages the PIDs. Just add myservice.conf to /etc/init (not /etc/inid.d) and the daemon will be started on boot and you can mangage it as a service. You do not have to make the file runnable or anything else
You can manage the service as normal for example
service myservice restart
service myservice status
...
My Config-File:
description "myservice"
author "your name"
start on runlevel [3]
stop on shutdown
expect fork
script
cd /home/username/
sudo -u username java -jar /home/username/myservice/myservice.jar >/home/username/myservice.log 2>&1
emit myservice_running
end script
This solution is really easy and works well on my Ubuntu 12.04 Server.
You have an error in this line:
sudo -u $USER -c nohup java -jar $DIR/JTS3ServerMod.jar $DIR 2>>/dev/null >>/dev/null&
You appear to be mixing the syntaxes of sudo and su. Before version 1.8, sudo had no -c option - you just give it the command to run after any other options. In 1.8 there is a -c option but it's not for specifying the command (it's for limiting resource usage to that of a given login class). sudo is printing an error message about this invalid syntax, but you're not seeing it because you're redirecting all the output to /dev/null.
Simply remove the -c to form a valid command:
sudo -u $USER nohup java -jar $DIR/JTS3ServerMod.jar $DIR 2>> /dev/null >> /dev/null &
Also, you can simplify the command a little by using the 2>&1 syntax to send stderr to the same handle as stdout, and there is no need for append mode when writing to /dev/null:
sudo -u $USER nohup java -jar $DIR/JTS3ServerMod.jar $DIR >/dev/null 2>&1 &

how to check whether one instance of shell script is already running - Linux

I have two different shell script say like
a.sh
b.sh
**code of a.sh**
#!/system/bin/sh
#some code
./xyz/b.sh &
Here we can see i am running b.sh through a.sh file which is postboot script. Each time when device gets reboot it is adding ./xyz/b.sh & which i am trying to avoid.
what i am trying to do :
i need to write a code in such a way that will find if ./system/xyz/b.sh & is already there then no need to add again.
Code :
if pgrep /xyz/b.sh > /dev/null 2>&1
then
echo aplog is running
exit 1
fi
these code is not running. Do not know where i am doing mistake.
Just try:
pgrep b.sh > /dev/null 2>&1
if [ 0 == $? ]
then
...
fi
pgrep will only work on process name, not full path to process name.
Try pgrep -f b.sh or pgrep -x b.sh instead of pgrep -x /xyz/b.sh
Hi test your file existence before creating it with:
filename="/fullpath/xyz/b.sh"
if [ -f "$filename" ]
then
echo "$filename found"
else
echo "$filename not found."
fi

Linux Script to check if process is running and act on the result

I have a process that fails regularly & sometimes starts duplicate instances..
When I run:
ps x |grep -v grep |grep -c "processname"
I will get:
2
This is normal as the process runs with a recovery process..
If I get
0
I will want to start the process
if I get:
4
I will want to stop & restart the process
What I need is a way of taking the result of ps x |grep -v grep |grep -c "processname"
Then setup a simple 3 option function
ps x |grep -v grep |grep -c "processname"
if answer = 0 (start process & write NOK & Time to log /var/processlog/check)
if answer = 2 (Do nothing & write OK & time to log /var/processlog/check)
if answer = 4 (stot & restart the process & write NOK & Time to log /var/processlog/check)
The process is stopped with
killall -9 process
The process is started with
process -b -c /usr/local/etc
My main problem is finding a way to act on the result of ps x |grep -v grep |grep -c "processname".
Ideally, I would like to make the result of that grep a variable within the script with something like this:
process=$(ps x |grep -v grep |grep -c "processname")
If possible.
Programs to monitor if a process on a system is running.
Script is stored in crontab and runs once every minute.
This works with if process is not running or process is running multiple times:
#! /bin/bash
case "$(pidof amadeus.x86 | wc -w)" in
0) echo "Restarting Amadeus: $(date)" >> /var/log/amadeus.txt
/etc/amadeus/amadeus.x86 &
;;
1) # all ok
;;
*) echo "Removed double Amadeus: $(date)" >> /var/log/amadeus.txt
kill $(pidof amadeus.x86 | awk '{print $1}')
;;
esac
0 If process is not found, restart it.
1 If process is found, all ok.
* If process running 2 or more, kill the last.
A simpler version. This just test if process is running, and if not restart it.
It just tests the exit flag $? from the pidof program. It will be 0 of process is running and 1 if not.
#!/bin/bash
pidof amadeus.x86 >/dev/null
if [[ $? -ne 0 ]] ; then
echo "Restarting Amadeus: $(date)" >> /var/log/amadeus.txt
/etc/amadeus/amadeus.x86 &
fi
And at last, a one liner
pidof amadeus.x86 >/dev/null ; [[ $? -ne 0 ]] && echo "Restarting Amadeus: $(date)" >> /var/log/amadeus.txt && /etc/amadeus/amadeus.x86 &
This can then be used in crontab to run every minute like this:
* * * * * pidof amadeus.x86 >/dev/null ; [[ $? -ne 0 ]] && echo "Restarting Amadeus: $(date)" >> /var/log/amadeus.txt && /etc/amadeus/amadeus.x86 &
cccam oscam
I adopted the #Jotne solution and works perfectly! For example for mongodb server in my NAS
#! /bin/bash
case "$(pidof mongod | wc -w)" in
0) echo "Restarting mongod:"
mongod --config mongodb.conf
;;
1) echo "mongod already running"
;;
esac
I have adopted your script for my situation Jotne.
#! /bin/bash
logfile="/var/oscamlog/oscam1check.log"
case "$(pidof oscam1 | wc -w)" in
0) echo "oscam1 not running, restarting oscam1: $(date)" >> $logfile
/usr/local/bin/oscam1 -b -c /usr/local/etc/oscam1 -t /usr/local/tmp.oscam1 &
;;
2) echo "oscam1 running, all OK: $(date)" >> $logfile
;;
*) echo "multiple instances of oscam1 running. Stopping & restarting oscam1: $(date)" >> $logfile
kill $(pidof oscam1 | awk '{print $1}')
;;
esac
While I was testing, I ran into a problem..
I started 3 extra process's of oscam1 with this line:
/usr/local/bin/oscam1 -b -c /usr/local/etc/oscam1 -t /usr/local/tmp.oscam1
which left me with 8 process for oscam1. the problem is this..
When I run the script, It only kills 2 process's at a time, so I would have to run it 3 times to get it down to 2 process..
Other than killall -9 oscam1 followed by /usr/local/bin/oscam1 -b -c /usr/local/etc/oscam1 -t /usr/local/tmp.oscam1, in *)is there any better way to killall apart from the original process? So there would be zero downtime?
If you changed awk '{print $1}' to '{ $1=""; print $0}' you will get all processes except for the first as a result. It will start with the field separator (a space generally) but I don't recall killall caring. So:
#! /bin/bash
logfile="/var/oscamlog/oscam1check.log"
case "$(pidof oscam1 | wc -w)" in
0) echo "oscam1 not running, restarting oscam1: $(date)" >> $logfile
/usr/local/bin/oscam1 -b -c /usr/local/etc/oscam1 -t /usr/local/tmp.oscam1 &
;;
2) echo "oscam1 running, all OK: $(date)" >> $logfile
;;
*) echo "multiple instances of oscam1 running. Stopping & restarting oscam1: $(date)" >> $logfile
kill $(pidof oscam1 | awk '{ $1=""; print $0}')
;;
esac
It is worth noting that the pidof route seems to work fine for commands that have no spaces, but you would probably want to go back to a ps-based string if you were looking for, say, a python script named myscript that showed up under ps like
root 22415 54.0 0.4 89116 79076 pts/1 S 16:40 0:00 /usr/bin/python /usr/bin/myscript
Just an FYI
The 'pidof' command will not display pids of shell/perl/python scripts. So to find the process id’s of my Perl script I had to use the -x option i.e. 'pidof -x perlscriptname'
I cannot get case to work at all.
Heres what I have:
#! /bin/bash
logfile="/home/name/public_html/cgi-bin/check.log"
case "$(pidof -x script.pl | wc -w)" in
0) echo "script not running, Restarting script: $(date)" >> $logfile
# ./restart-script.sh
;;
1) echo "script Running: $(date)" >> $logfile
;;
*) echo "Removed duplicate instances of script: $(date)" >> $logfile
# kill $(pidof -x ./script.pl | awk '{ $1=""; print $0}')
;;
esac
rem the case action commands for now just to test the script. the above pidof -x command is returning '1', the case statement is returning the results for '0'.
Anyone have any idea where I'm going wrong?
Solved it by adding the following to my BIN/BASH Script:
PATH=$PATH:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
In case you're looking for a more modern way to check to see if a service is running (this will not work for just any old process), then systemctl might be what you're looking for.
Here's the basic command:
systemctl show --property=ActiveState your_service_here
Which will yield very simple output (one of the following two lines will appear depending on whether the service is running or not running):
ActiveState=active
ActiveState=inactive
And if you'd like to know all of the properties you can get:
systemctl show --all your_service_here
If you prefer that alphabetized:
systemctl show --all your_service_here | sort
And the full code to act on it:
service=$1
result=`systemctl show --property=ActiveState $service`
if [[ "$result" == 'ActiveState=active' ]]; then
echo "$service is running" # Do something here
else
echo "$service is not running" # Do something else here
fi
If you are using CentOS, no need to write a script and set cron job. Here is one of the smartest ways to ensure systemd services restart on failure.
Make following changes to /usr/lib/systemd/system/mariadb.service
Then under the [Service] section in the file, add the following 2 lines:
Restart=always
RestartSec=3
After saving the file we need to reload the daemon configurations to ensure systemd is aware of the new file
systemctl daemon-reload
Read the following link for the complete steps -
https://jonarcher.info/2015/08/ensure-systemd-services-restart-on-failure/

Resources