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

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

Related

Kick any user that has been idle for more than an hour on Linux Server

#!/bin/bash
while read -r line; do
# Extract the username and idle time
username=$(echo "$line" | awk '{print $1}')
idle=$(echo "$line" | awk '{print $4}')
idle=$(echo "$idle" | sed 's/^0*//')
idle_seconds=$((idle*60))
last_active=$((now-idle_seconds))
one_hour_ago=$((now-3600))
if [ "$idle_seconds" -gt 3600 ] && [ "$last_active" -lt "$one_hour_ago" ]; then
pkill -kill -t "$username"
fi
done < <(w -h)
This is what I have so far but it does not seem to be extracting the idle time correctly. I get this error:
line 16: 9:47: syntax error in expression (error token is ":47")
Any help would be appreciated thanks. (My server is running Ubuntu 20.04)
Not addressing the error you're seeing, but trying to enforce the 1 hour idle problem without scripting.
Create a file under /etc/profile.d/ (as root):
echo "export TMOUT=3600" > /etc/profile.d/tmout.sh

before executing script.sh, Check script.sh running or not, if its running kill and continue

CMD# bash script.sh
#!/bin/bash
PRE_CHECK=$0
PROCESS_ID=`ps -ef | grep "$PRE_CHECK" | egrep -v 'grep' | awk '{print $2}'`
[[ ! -z $PROCESS_ID ]] && kill -9 $PROCESS_ID
echo ""
echo ""
echo ""
In order to know this, you need to know your own process ID. This is stored in the variable $$, so you need to kill all PIDs, except for that one.

Shellscript to monitor a log file if keyword triggers then run the snmptrap command

Is there a way to monitor a log file using shell script like
tail -f /var/log/errorlog.txt then if something like down keyword appears, then generate SNMPTRAP to snmp manager and continues the monitoring
I have a SNMP script available to generate SNMPTrap and it looks like
snmptrap -v v2c -c community host "Error message"
Lets the say the script name is snmp.sh
My question is how to perform the below operation
tail the logs
if keyword[down] matches then use snmp.sh script to send alert
else leave
As per the suggestion i tried this
tail -F /data/log/test.log |
egrep -io 'got signal 15 | now exiting' |
while read -r line ;
do
case "$line" in
"got signal 15")
echo "hi"
;;
"now exiting")
echo "hi2"
;;
*)
esac
done
but the problem is tail is not working here with case statement, whenever the new log details added its not going to the case statement and echos the output
I could get the output if i use cat/less/more
Could you someone please tell what mistake i have done here ?
Thanks in advance
It sounds like the pattern you want is this:
tail -f /var/log/errorlog.txt | grep -e down -e unmounted | while read -r line
do
case "$line" in
down)
./snmp.sh …
;;
unmounted)
./snmp.sh …
;;
*)
echo "Unhandled keyword ${line}" >&2
exit 1
esac
done
try
tail -f /var/log/errorlog.txt | grep "down" | while read line; do snmp.sh; done

Trying to make a live /proc/ reader using bash script for live process monitoring

Im trying to make a little side project script to sit and monitor all of the /proc/ directories, for the most part I have the concept running and it works(to a degree). What im aiming for here is to scan through all the files and cat their status files and pull out the appropriate info, and then I would like to run this process in an infinite loop to give me live updates of when something is running on and dropping off of the scheduler. Right now every time you run the script, it will print 50+ blank lines and every single time it hits the proper regex it will print it correctly, but Im aiming for it to not roll down the screen the way it does. Any help at all would be appreciated.
regex="[0-9]"
temp=""
for f in /proc/*; do
if [[ -d $f && $f =~ /proc/$regex ]]; then
output=$(cat $f/status | grep "^State") #> /dev/null
process_id=$(cut -b 7- <<< $f)
state=$(cut -b 10-19 <<< $output)
tabs 4
if [[ $state =~ "(running)" ]]; then
echo -e "$process_id:$state\n" | sort >> temp
fi
fi
done
cat temp
rm temp````
To get the PID and status of running all processes, try:
awk -F':[[:space:]]*' '/State:/{s=$2} /Pid:/{p=$2} ENDFILE{if (s~/running/) print p,s; p="X"; s="X"}' OFS=: /proc/*/status
To get this output updated every second:
while sleep 1; do awk -F':[[:space:]]*' '/State:/{s=$2} /Pid:/{p=$2} ENDFILE{if (s~/running/) print p,s; p="X"; s="X"}' OFS=: /proc/*/status; done

bash: loop through procces output and terminate the process

I need some help with the following:
I use linux to script commands sent to a device. I need to submit a grep logcat command to the device and then iterate its output as it is being generated and look for a particular string. Once this string is found I want my script to move to the following command.
in pseudocode
for line in "adb shell logcat | grep TestProccess"
do
if "TestProccess test service stopped" in line:
print line
print "TestService finished \n"
break
else:
print line
done
adb shell logcat | grep TestProcess | while read line
do
echo "$line"
if [ "$line" = "TestProces test service stopped" ]
then echo "TestService finished"
break
fi
done
adb shell logcat | grep -Fqm 1 "TestProcess test service stopped" && echo "Test Service finished"
The grep flags:
-F - treat the string literally, not as a regular expression
-q - don't print anything to standard output
-m 1 - stop after the first match
The command after && only executes if grep finds a match. As long as you "know" grep will eventually match and want to unconditionally continue once it returns, just leave off the && ...
You could use an until loop.
adb shell logcat | grep TestProccess | until read line && [[ "$line" =~ "TestProccess test service stopped" ]]; do
echo $line;
done && echo -n "$line\nTestService finished"

Resources