check if process is running in bash script - bash

how can i check if a process is running, if it is running then echo "process is running" and keep them from using that process til its finished. i have this piece of code but i cant get it to not allow them to use that process after it echos:
#!/bin/bash
SERVICE=EXAMPLE
if ps ax | grep -v grep | grep -v grep | grep $SERVICE > /dev/null
then
echo -e ""
echo -e "${LIGHTRED}[!] ${WHITE}Please wait till process is finished."
fi

It seems you want to write a loop, not a single if statement.
And you probably want to sleep a bit between checking the condition.
#!/bin/bash
SERVICE=EXAMPLE
while ps ax | grep -v grep | grep "$SERVICE" > /dev/null
do
echo
echo -e "${LIGHTRED}[!] ${WHITE}Please wait till process is finished."
sleep 60
fi
The condition can be simpler if you have pgrep:
while pgrep "$SERVICE" >/dev/null
(Or the simpler while pgrep -q "$SERVICE" if your implementation of pgrep supports it.)
When there is no matching process (already finished or not started yet),
then the script will not produce any output.
If you want to get some output in that case,
then you can rework like this:
while true
do
if pgrep "$SERVICE" > /dev/null; then
echo
echo -e "${LIGHTRED}[!] ${WHITE}Please wait till process is finished."
sleep 60
else
echo "Process '$SERVICE' not running"
break
fi
fi
To print the message only once and just wait until the process is no longer running:
is_running() {
pgrep "$SERVICE" > /dev/null
}
if is_running; then
echo -e "${LIGHTRED}[!] ${WHITE}Please wait till process is finished."
while true; do
sleep 60
is_running || break
done
else
echo "Process '$SERVICE' not running"
fi

Another solution
#!/bin/bash
tput civis # hide cursor
until ! ps -ef | grep "$SERVICE" | grep -v "grep" > /dev/null; do
while ps -ef | grep "$SERVICE" | grep -v "grep" > /dev/null; do
echo -en "\r${LIGHTRED}[!] ${WHITE}Please wait till process is finished."
done
printf "\r%80s" "" # clear line
echo -en "\rProcess '$SERVICE' is completed!\n"
done
tput cnorm # show cursor again
This solution is useful also if you have multiple instance of the service together.

Related

Needed shell script which will check for not responding apps and kill them

Need to execute on MacOS.
Most of the solution is giving status running or stopped but for Not Responding state not having any solution.
tried solutions like this
pgrep "$1" 2>&1 > /dev/null
echo $?
if [ $? -eq 0 ]
then
{
echo " "$1" PROCESS RUNNING "
ps -ef | grep $1 | grep -v grep | awk '{print $2}'| xargs kill -9
}
else
{
echo " NO $1 PROCESS RUNNING"
};fi

self destruct subprocess in while loop (Bash)

I am trying to tail a file periodically. Problem is that i must somehow kill the last process in the event of a ctrl+c or sudden closure of terminal, else tail process will remain running.
1.The following script will work, but last process might remain open if session is terminated before kill.
#cat test.sh
echo "Choose the polling interval: "
read interval
while :
do
tail -f -n0 /var/log/messages &
pid=$!
sleep "$interval"
kill "$pid"
done
Output:
#./test.sh
Choose the polling interval:
2
./test.sh: line 9: 8263 Terminated tail -f -n0 /var/log/messages
./test.sh: line 9: 8265 Terminated tail -f -n0 /var/log/messages
Ctrl^C.
/test.sh: line 9: 8267 Terminated tail -f -n0 /var/log/messages
#ps auxfww | grep [t]ail | wc -l
1
2.If i try to make the killing in background, i get many errors as seen bellow.
#cat test_bg.sh
echo "Choose the polling interval: "
read interval
while :
do
tail -f -n0 /var/log/messages &
pid=$!
(sleep "$interval" ; kill "$pid") &
done
Output:
#./test_bg.sh
Choose the polling interval:
2
tail: inotify cannot be used, reverting to polling: Too many open files
........
tail: inotify cannot be used, reverting to polling: Too many open files
How can i kill last process in the event of a sudden interruption?
I managed to make it work with wait like this:
echo "Choose the polling interval: "
read interval
while :
do
echo "starting tail"
tail -f -n0 /var/log/messages &
pid=$!
echo "pid is $pid"
echo "checking ps for tail"
ps -ef | grep $pid
echo "checked ps for tail"
(sleep "$interval" ; kill "$pid") &
killpid=$!
echo "counting $interval seconds"
sleep $interval
echo ""
echo "killpid is $killpid"
wait $killpid
echo ""
echo "$interval seconds have passed"
echo "killpid $killpid should be dead now"
echo ""
echo "checking ps for kill"
ps -ef | grep $killpid
echo "checked ps for kill"
echo ""
echo "tail pid $pid should be dead now"
echo "rechecking ps for tail"
ps -ef | grep $pid
echo "rechecked ps for tail"
echo ""
done

Matching one line from continuous stream in Linux shell

How can I make the following commands exit immediately after the first line is matched? I understand that SIGPIPE is not sent to cat until it tries to write next time (tail bug report), but I don't understand how to solve this issue.
cat <( echo -ne "asdf1\nzxcv1\nasdf2\n"; sleep 5; echo -ne "zxcv2\nasdf3\n" ) | grep --line-buffered zxcv | head --lines=1
cat <( echo -ne "asdf1\nzxcv1\nasdf2\n"; sleep 5; echo -ne "zxcv2\nasdf3\n" ) | grep --max-count=1 zxcv
NB: I actually had tail --follow before the pipesign, but replaced it with catand sleep to simplify testing. The shell in question is GNU bash 4.4.12(1)-release, and I'm running MINGW that came with Git-for-Windows 2.12.2.2.
CLARIFICATION: I have a jboss server which is started in a docker container and which outputs couple thousand lines of text within three minutes to a log file. My goal is to watch this file until a status line is printed, analyze line contents and return it to a human or Jenkins user. Of course, I can grep whole file and sleep for a second in a loop, but I'd rather avoid this if at all possible. Furthermore, this looping would interfere with my usage of timeout routine to limit maximum execution time. So, is it possible to listen for a pipe until a certain line appears and stop as soon as that happens?
Related question: Why does bash ignore SIGINT if its currently running child handles it?
Interesting question! I've verified that head dies after printing the first line (removed background job noise):
$ (printf '%s\n' a b a; sleep 5; printf '%s\n' a) | grep --line-buffered a | head --lines=1 & sleep 1; pstree $$
a
bash─┬─bash───sleep
├─grep
└─pstree
At first glance, it appears head doesn't send SIGPIPE, but I get conflicting information from running strace grep:
$ (printf '%s\n' a b a; sleep 10; printf '%s\n' a) | strace grep --line-buffered a | head --lines=1
…
--- SIGPIPE {si_signo=SIGPIPE, si_code=SI_USER, si_pid=21950, si_uid=1000} ---
+++ killed by SIGPIPE +++
… and killing grep:
$ (printf '%s\n' a b a; sleep 10; printf '%s\n' a) | grep --line-buffered a | head --lines=1 & sleep 1; kill -PIPE $(pgrep grep); sleep 5; pstree $$
a
bash─┬─bash───sleep
└─pstree
Killing grep and then sleep fixes the issue:
$ (printf '%s\n' a b a; sleep 10; printf '%s\n' a) | grep --line-buffered a | head --lines=1 & sleep 1; kill -PIPE $(pgrep grep); sleep 1; kill -PIPE $(pgrep sleep); sleep 5; pstree $$
a
bash───pstree
Conclusion: WTF?
I've ended up doing following to be able to break following log both on a matching line and after a timeout.
#!/bin/sh
TOP_PID=$$
container_id="$1"
LOG_PATH=/opt/jboss/jboss-eap-6.2/standalone/log/server.log
await_startup () {
status=$(check_status)
follow_log --timeout $timeout &
local bgjob_pid; local bgjob_status;
bgjob_pid=$(jobs -p)
test -n "$bgjob_pid" || die "Could not start background job to follow log."
bgjob_status=true
while [ "$status" = "not started" ] && $bgjob_status; do
sleep 1s
status=$(check_status)
if kill -0 $bgjob_pid 2>/dev/null; then
bgjob_status=true
else
bgjob_status=false
fi
done
kill -KILL $bgjob_pid 2>/dev/null
}
follow_log () {
# argument parsing skipped...
docker exec $container_id timeout $timeout tail --follow=name ---disable-inotify --max-unchanged-stats=2 /$LOG_PATH
}
check_status () {
local line;
line=$(docker exec $container_id grep --extended-regexp --only-matching 'JBoss EAP .+ started.+in' /$LOG_PATH | tail --lines=1)
if [ -z "$line" ]; then
printf "not started"
elif printf "%s" "$line" | grep --quiet "with errors"; then
printf "started and unhealthy"
else
printf "healthy"
fi
}
die () {
test -n "$1" && printf "%s\n" "$1"
kill -s TERM $TOP_PID
return 1
} 1>&2

reading variables to ps ax script

Hi I've been searching on the forum but I cant seem to get this right. I am trying to create a script that asks the user which process they are searching for then returns with a 1 if the process is running.
This works:
#!/bin/bash
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"
fi
I want to add this to the script:
echo -e "please enter process name: \c"
read word
for something like:
#!/bin/sh
echo -e "please enter process name: \c"
read input_variable
if ps ax | grep -v grep | grep $varname > /dev/null
then
echo "$SERVICE service running, everything is fine"
else
echo "$SERVICE is not running"
fi
Use pgrep to search for processes:
read process_name
if pgrep "${process_name}" >/dev/null 2>&1 ; then
"echo ${process_name} found"
else
"echo ${process_name} not found"
fi

Bash Script issue, command not found, PATH seems to be correct

I have a issue with my Script, i am just trying to fingure out if my screen session is running or not (line 19).
The rest of the script is working.
#!/bin/bash
echo $PATH // /usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
echo "0"
content=$(wget http://interwebs.com/index.php?page=count -q -O -)
z=$(($content / 5))
z=$(($z + 1))
echo $z // 4
lockfile=/var/tmp/mylock
if ( set -o noclobber; echo "$$" > "$lockfile") 2> /dev/null; then
trap 'rm -f "$lockfile"; exit $?' INT TERM EXIT
# do stuff here
x=1
count=0
while [ $x -le $z ]
do
$req ="$(ps -ef | grep -i mystatus$count | grep -v grep)"
if [ "$req" = "" ]; then
# run bash script
screen -amds mystatus$count /usr/bin/wget --spider interwebs.com/index.php?page=cronwhatsoever$(( $count +1))-$(( $count +5))
else
echo "Cron running"
fi
x=$(( $x + 1 ))
count=$(( $count +5))
done
# clean up after yourself, and release your trap
rm -f "$lockfile"
trap - INT TERM EXIT
else
echo "Lock Exists: $lockfile owned by $(cat $lockfile)"
fi
sleep 15
It returns line 19: =: command not found. Actually running:
ps -ef | grep -i bukkit | grep -v grep
Works without issues if i run it directly in my Terminal, so any idea how to solve this issue?
I guess it something PATH related but grep is located in /bin/grep.
$req ="$(ps -ef | grep -i mystatus$count | grep -v grep)"
should be
req="$(ps -ef | grep -i mystatus$count | grep -v grep)"
Don't use $ on the left-hand side of an assignment, and you must not have spaces around the =

Resources