Check if a screen session is running and automating via cron - linux

So trying to get this to work, not familiar with linux but cobbled this together just having some problems... also the echo ''$NOW' Server was down.... Started !' ...seems to make to "server was ddown..."etc onto a line below which is weird because if I use the same line in another script the whole thing goes onto 1 line in the servercheck.txt file.
in check.sh >>
#!/bin/bash
if screen -list | grep -q "minecraft"; then
echo "Server is running!"
cd /home/minecraft/
teststart.sh
NOW=$(date +"%b-%d %H:%M")
echo ''$NOW' Server was down.... Started !' >> /home/minecraft/servercheck.txt;
else
echo "Server dead"
fi
errors...
: not found: check.sh:
Server is running!
: not found: check.sh: teststart.sh
: not found: check.sh:
And how to run teststart.... also the: not found: errors
this has to go into a cron aswel for the user minecraft, any help with that aswel wanting it to run every 5mins.

With
if screen -list | grep -q "minecraft";
you're only checking if the screen is running, not the server. Instead you can use something like
ps -ef | grep -i bukkit | grep -v grep; echo $?
If return is 0 the (bukkit) server is running if return is 1 the server is not running.
To remove the \n after $NOW use
echo -ne ''$NOW' Server was down.... Started !\n' >> /home/minecraft/servercheck.txt;

Related

Bash script to write all occurrences of application crash to a text file

I can't find how to structure my while loop properly to log to a text file all crashes of a given Linux application. I would like to get a prompt so I can input the application name and then a loop to watch the pid of the application. If the pid is null I wanted to log the timestamp in a text file and continue the loop. If still in null at the second iteration, don't log anything, keep monitoring until there are other crashes and other logs... and so on until the script stops with CTRL+C.
I've tried multiple variations of this script without luck. I think I need tips on how to think of a "loop structure" to achieve whatever goals...
read -p "What is the name of the application you want to monitor?" appname
pidofapp=`ps -elf | grep "$appname" | grep -v grep | awk '{print $4}'`
pidofappcheck=`ps -elf | grep "$appname" | grep -v grep | awk '{print $4}'`
while :
do
if [[ ! -z "$pidofappcheck" ]] ; then
pidwasnull=true
pidofappcheck=`ps -elf | grep "$appname" | grep -v grep | awk '{print $4}'`
if [[ "$pidofapp" == "$pidofappcheck" ]] ; then
printf "Still monitoring...\n"
sleep 5
elif [[ "$pidwasnull" == true ]] ; then
continue
fi
echo "FAILURE: Crash occurred at: "$(date)" - Crashes will be logged in the monitoring tool directory under results.txt"
date >> ./results.txt
fi
done
As it is right now, the script will echo:
What is the name of the application you want to monitor?running
Still monitoring...
FAILURE: Crash occurred at: Wed May 22 01:44:53 EDT 2019 - Crashes will be logged in the monitoring tool directory under results.txt
Still monitoring...
FAILURE: Crash occurred at: Wed May 22 01:44:58 EDT 2019 - Crashes will be logged in the monitoring tool directory under results.txt
Thanks in advance for any help.
Try something like this
#!/bin/bash
getpidofapp() {
# pid=$(ps -elf | grep "$1" | grep -v grep | awk '{print $4}' | head -1)
pid=$(pgrep "$1" | head -1)
test -n "${pid}" || { echo "Is ${appname} running?"; exit 1; }
}
read -rp "What is the name of the application you want to monitor?" appname
app_pid=$(getpidofapp "${appname}")
while : ; do
lastpid=$(getpidofapp "${appname}")
if [[ "${app_pid}" == "${lastpid}" ]] ; then
printf "Still monitoring...\n"
else
crashtxt="Crashes will be logged in the monitoring tool directory under results.txt"
echo "FAILURE: Crash occurred at: $(date) ${crashtxt}"
date >> ./results.txt
fi
sleep 5
done
So I have been able to find a solution based on what #Walter A wrote. Here is what I've used. It's working as expected so far.
#!/bin/bash
read -rp "What is the name of the application you want to monitor?" appname
app_pid=$(pidof "$appname")
#echo "First PID of "$appname" is "$app_pid""
while : ; do
lastpid=$(pidof "$appname")
if [[ "${app_pid}" == "${lastpid}" ]] ; then
printf "Still monitoring...\n"
else
crashtxt="Crashes will be logged in the monitoring tool directory under results.txt"
echo "FAILURE: Crash occurred at: $(date) ${crashtxt}"
date >> ./results.txt
app_pid="$lastpid"
fi
sleep 5
done
So this script will basically check the PID of the given app until you CTRL+C. If the PID of the app changes while the script is running. It will output the timestamps of when it occurred in a "results.txt" file and it will keep checking it until you press CTRL+C. Therefore I am going to use this to log all crash occurrences of my apps. Thanks a lot #Walter A

Checking if a node.js app has started properly using bash

I wrote a node.js application and have written a bash script to start it and verify if it's running. I have my script run npm start & first, then I have a check to see if the ports I want open are open using netstat. The check works fine when I run it after the script is run, but during the running of the script, the check fails because the server has not fully started before the check is run. My code is below:
echo "Starting the server..."
npm start & > /dev/null 2>&1
if [[ -z $(sudo netstat -tulpn | grep :$portNum | grep node) ]] ; then
echo -e "\tPort $portNum is not in use, something went wrong. Exiting."
else
echo -e "\tPort $portNum is in use!"
fi
Is there a good way to take the above script and change it so that the check doesn't occur until the server is fully started? I don't want to use sleep if I can help it.
You can use a wait call:
echo "Starting the server..."
npm start & > /dev/null 2>&1
wait
if [[ -z $(sudo netstat -tulpn | grep :$portNum | grep node) ]] ; then
echo -e "\tPort $portNum is not in use, something went wrong. Exiting."
else
echo -e "\tPort $portNum is in use!"
fi
The only limitation to this is that if npm daemonizes itself then it's no longer a child of the script so the wait command will have no effect (the reason for this is that a process daemonizes itself by terminating and spawning a new process that inherits its role).

how to write a while loop in a bash file

I am trying to write a while loop in bash as below:
while [!(netstat -pnlt | grep ":9393" | wc -l)];
do
echo "server not ready... waiting..."
sleep 2
done
I get
syntax error near unexpected token `netstat'
from console
what I want to do is:
to grep the service that using port 9393, count its lines. If lines number is 0,
it means the service is not running, so I will keep it wait.
OS: debian:jessie
please help me correct it... I looked up a lot of documents
Your test syntax is incorrect. Have a look at the man page for usage, or at the examples all over the Internet.
while [[ $(netstat -pnlt | grep -c ":9393 .*LISTEN") -eq '1' ]]; do
echo "server not ready... waiting..."
sleep 2
done
But with the edit you made to your question, the following would be better:
while ! netstat -pnlt | grep -q ":9393 .*LISTEN"; do
echo "server not ready... waiting..."
sleep 2
done
It's better to use lsof
while ! lsof -iTCP:9393 -sTCP:LISTEN >/dev/null; do
echo "server not ready... waiting..."
sleep 2
done

Linux self-healing script to check some process

Im new with Linux scripts, I need help to create one script with check some installed processes on a server and if one of these services is not running restart it, and recheck again those services and if there any error print it with echo as below :
dsisrv (DSI service) (7384) Running
midaemon (measurement interface) (1412) Running
misrv (measurement interface service) (1384) Running
perfalarm (Alarm generator) Stopped
perfalarmsrv (Alarm generator service) Stopped
scopent (data collector) Stopped
scopesrv (collector service) Stopped
perfd (Real Time Metric Access Daemon) (7888) Running
perfdsrv (Real Time Metric Access Service) (9020) Running
ttd (transaction tracking) (1808) Running
in case any of above services is stopped, the script to run restart command.
Appreciate if any one help me to start with this script
Regards,
#!/bin/sh
SERVICE='httpd'
if ps ax | grep -v grep | grep $SERVICE > /dev/null
then
echo "$SERVICE service running, everything is fine"
else
echo "$SERVICE is not running" echo "$SERVICE is not running!" | mail -s "$SERVICE down" root
fi
Just add the service your looking for, this will mail you if the service goes down. Im assuming your using bash so enjoy.
i did simple script i hope this will be helpful please run this script as a root and add your services or daemons inside declaration array
declare -a service=(vsftpd sshd)
full script
#!/bin/bash
declare -a service=(vsftpd sshd) ##declaration array
for x in ${service[#]} ##array with
do
process=` ps -A | grep $x | awk '{print $4}' ` ### all process output
all_services=`echo $x`
line_no=` ps -A | sed -n '/'$all_services'/=' `
if ` ps -A | grep ${process[#]} > 0 ` ## condition to check if service available or not
then
echo "status running", " `ps -A | sed -n ''$line_no''p | awk ' {print $1 $4}'` " ## service up running
else
service $all_services start ### start the daemon again
fi
done

How to set up an automatic (re)start of a background ssh tunnel

I am a beginner user of linux, and also quite newbie at ssh and tunnels.
Anyway, my goal is to maintain a ssh tunnel open in background.
In order to do that, I wrote the following batch that I then added into crontab (the batch is automatically processed every 5 minutes during workdays and from 8am to 9pm).
I read in some other thread in stackoverflow that one should use autossh that will ensure the ssh will always be ok through a recurrent check. So did I....
#!/bin/bash
LOGFILE="/root/Tunnel/logBatchRestart.log"
NOW="$(date +%d/%m/%Y' - '%H:%M)" # date & time of log
if ! ps ax | grep ssh | grep tunnelToto &> /dev/null
then
echo "[$NOW] ssh tunnel not running : restarting it" >> $LOGFILE
autossh -f -N -L pppp:tunnelToto:nnnnn nom-prenom#193.xxx.yyy.zzz -p qqqq
if ! ps ax | grep ssh | grep toto &> /dev/null
then
echo "[$NOW] failed starting tunnel" >> $LOGFILE
else
echo "[$NOW] restart successfull" >> $LOGFILE
fi
fi
My problem is that sometimes the tunnel stops working, although every thing looks ok (ps ax | grep ssh > the result shows the two expected tasks : autossh main task and the ssh tunnel itself). I actually know about the problem cause the tunnel is used by a third party software that triggers an error as soon as the tunnel is no more responding.
SO I am wondering how I should improve my batch in order It will be able to check the tunnel and restart it if it happens to be dead. I saw some ideas in there, but it was concluded by the "autossh" hint... which I already use. Thus, I am out of ideas... If any of you have, I'd gladly have a look at them!
Thanks for taking interest in my question, and for your (maybe) suggestions!
Instead of checking the ssh process with ps you can do the following trick
create script, that does the following and add it to your crontab via crontab -e
#!/bin/sh
REMOTEUSER=username
REMOTEHOST=remotehost
SSH_REMOTEPORT=22
SSH_LOCALPORT=10022
TUNNEL_REMOTEPORT=8080
TUNNEL_LOCALPORT=8080
createTunnel() {
/usr/bin/ssh -f -N -L$SSH_LOCALPORT:$REMOTEHOST:SSH_REMOTEPORT -L$TUNNEL_LOCALPORT:$REMOTEHOST:TUNNEL_REMOTEPORT $REMOTEUSER#$REMOTEHOST
if [[ $? -eq 0 ]]; then
echo Tunnel to $REMOTEHOST created successfully
else
echo An error occurred creating a tunnel to $REMOTEHOST RC was $?
fi
}
## Run the 'ls' command remotely. If it returns non-zero, then create a new connection
/usr/bin/ssh -p $SSH_LOCALPORT $REMOTEUSER#localhost ls >/dev/null 2>&1
if [[ $? -ne 0 ]]; then
echo Creating new tunnel connection
createTunnel
fi
In fact, this script will open two ports
port 22 which will be used to check if the tunnel is still alive
port 8080 which is the port you might want to use
Please check and send me further questions via comments
(I add this as an answer since there is not enough room for it un a comment)
Ok, I managed to make the batch run to launch the ssh tunnel (I had to specify my hostname instead of localhost in order it could be triggered) :
#!/bin/bash
LOGFILE="/root/Tunnel/logBatchRedemarrage.log"
NOW="$(date +%d/%m/%Y' - '%H:%M)" # date et heure du log
REMOTEUSER=username
REMOTEHOST=remoteHost
SSH_REMOTEPORT=22
SSH_LOCALPORT=10022
TUNNEL_REMOTEPORT=12081
TUNNEL_SPECIFIC_REMOTE_PORT=22223
TUNNEL_LOCALPORT=8082
createTunnel() {
/usr/bin/ssh -f -N -L$SSH_LOCALPORT:$REMOTEHOST:$SSH_REMOTEPORT -L$TUNNEL_LOCALPORT:$REMOTEHOST:$TUNNEL_REMOTEPORT $REMOTEUSER#193.abc.def.ghi -p $TUNNEL_SPECIFIC_REMOTE_PORT
if [[ $? -eq 0 ]]; then
echo [$NOW] Tunnel to $REMOTEHOST created successfully >> $LOGFILE
else
echo [$NOW] An error occurred creating a tunnel to $REMOTEHOST RC was $? >> $LOGFILE
fi
}
## Run the 'ls' command remotely. If it returns non-zero, then create a new connection
/usr/bin/ssh -p $SSH_LOCALPORT $REMOTEUSER#193.abc.def.ghi ls >/dev/null 2>&1
if [[ $? -ne 0 ]]; then
echo [$NOW] Creating new tunnel connection >> $LOGFILE
createTunnel
fi
However, I got some immediate message (below) when the tunnel is running and when cron tries to lauch the batch again... sounds like it cannot listen to it. Also since I need some time to get a proof , I can't say yet it will successfully restart if the tunnel is out.
Here's the response to the second start of the batch.
bind: Address already in use channel_setup_fwd_listener: cannot listen
to port: 10022 bind: Address already in use
channel_setup_fwd_listener: cannot listen to port: 8082 Could not
request local forwarding.

Resources