How to run one command if a previous command succeeds, otherwise run another command - bash

I am trying to check if a process (assume it is called some_process) is running on a server. If it is, then echo 1, otherwise echo 0.
This is the command that I am using but it only works partially (more info below). Note that I need to write the script in one line.
ps aux | grep some_proces[s] > /tmp/test.txt && if [ $? -eq 0 ]; then echo 1; else echo 0; fi
Note: The [s] in some_proces[s] is to prevent grep from returning itself.
If some_process is running, then "1" gets echoed, which is fine. However, if some_process is not running, nothing gets echoed.

There is no need to explicitly check $?. Just do:
ps aux | grep some_proces[s] > /tmp/test.txt && echo 1 || echo 0
Note that this relies on echo not failing, which is certainly not guaranteed. A more reliable way to write this is:
if ps aux | grep some_proces[s] > /tmp/test.txt; then echo 1; else echo 0; fi

&& means "and if successful"; by placing your if statement on the right-hand side of it, you ensure that it will only run if grep returns 0. To fix it, use ; instead:
ps aux | grep some_proces[s] > /tmp/test.txt ; if [ $? -eq 0 ]; then echo 1; else echo 0; fi
(or just use a line-break).

Use grep -vc to ignore grep in the ps output and count the lines simultaneously.
if [[ $(ps aux | grep process | grep -vc grep) > 0 ]] ; then echo 1; else echo 0 ; fi

You can make full use of the && and || operators like this:
ps aux | grep some_proces[s] > /tmp/test.txt && echo 1 || echo 0
For excluding grep itself, you could also do something like:
ps aux | grep some_proces | grep -vw grep > /tmp/test.txt && echo 1 || echo 0

pgrep -q some_process && echo 1 || echo 0
more oneliners here

Related

Count is not Captured in Shell Script Variable

I am trying to capture the number of active processes by running a command and trying to capture the result in a variable of shell script, but unfortunately, nothing is getting captured. The code is as below:
#!/bin/ksh
## Checking whether or not the Previous Build is Completed
count_build_status=`ps -ef | grep BDD_PreCheck.sh | grep -c FT_BGmgmt` | tee -a ${logFile}
echo "The Value of Count Build Status is $count_build_status"
if [[ "${count_build_status}" != "0" ]]
then
echo INFO - The previous build has not ended yet. Please Wait for some time or contact the Administrator | tee -a $logFile
exit 1;
fi
exit 0;
Here, ps -ef | grep BDD_PreCheck.sh | grep -c FT_BGmgmt gives result as 0 if executed individually, but the value stored in 'count_build_status' is null.
Can anyone help?
The problem here is backtick, which does not assign value to the variable when tee'ing is not done inside backtick. It should be included at the end of logFile as in the code below.
#!/bin/bash
logFile=log.txt
## Checking whether or not the Previous Build is Completed
count_build_status=`ps -ef | grep BDD_PreCheck.sh | grep -c FT_BGmgmt | tee -a ${logFile}`
echo "The Value of Count Build Status is $count_build_status"
if [[ "${count_build_status}" != "0" ]]
then
echo INFO - The previous build has not ended yet. Please Wait for some time or contact the Administrator | tee -a $logFile
exit 1;
fi
exit 0;
example: capture output of a cmd-line to a variable and append a logfile with tee:
var=`ps -ef | grep 0 | grep -c 1 | tee -a log`
echo $var

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 =

If or while loop inside case command positional parameters

Being relatively new to anything other than bash scripting, I have created a script to
check if a process is running
output PID's to the shell
if not prompt user input and start etc/etc.
I've moved onto positional parameters and can't see where I'm going wrong:
if [ "$1" == "" ]; then
proc_finder
elif [ $1 != "" ];then
case $1 in
-p | --process )
shift
z=$(ps aux |grep $1 |grep -v grep > /dev/null)
if [ ! -z "$z" ]; then
echo "YES"
else
echo "NO"
fi
;;
* )
echo "Usage -p (process)"
esac
fi
This always seems to return yes even when putting in -p test for example. I know im doing something fundamentally wrong, looking at the verbose output the grep -v grep is being done last hence I believe it always returnes an exit state of 0.
Shouldn't that be if [ $? -eq 0 ]?
EDIT 1
You can try this:
z=`ps aux | grep $1 | grep -v grep > /dev/null`
if [ ! -z "$z" ]; then
echo "YES"
else
echo "NO"
fi
If $z is not empty (-z: test for zero-length string) this implies the process was found with the ps command.
EDIT 2
The ps ... grep ... grep is being redirect to /dev/null. That means z will contain nothing. remove the redirection and z should have some output.
z=`ps aux | grep $1 | grep -v grep`
EDIT 3
Alternatively, you can just do this:
ps aux | grep $1 | grep -v grep > /dev/null 2>&1
if [ $? -eq 0 ]; then
echo "YES"
else
echo "NO"
fi
In this case, you are not saving the grep output. That's good if you don't really need it.

Error Handling on bash script

Infinite loop on bash script and I want to run forever but (I guess) something goes wrong script is killed. Is there any way like try-catch, just continue to running forever, unconditionaly.
#!/bin/bash
iteration=0
for (( ; ; ))
do
process_id=`ps -ef | grep java | grep TEST | awk '{print $2}' `
kill_command='kill -3 '$process_id
time=`date | awk '{print substr($4,0,5)}' `
last_write=`ls -l /files/*.txt | awk '{print $8}' `
if [ "$time" != "$last_write" ]
then
$kill_command
sleep 1
$kill_command
sleep 1
$kill_command
sleep 1
/test/show_queue.sh
fi
let "iteration+=1"
if [ "$iteration" == "30" ]
then
let "iteration=0"
$kill_command
echo '------------' >> memory_status.log
date >> memory_status.log
prstat -n 7 1 1 >> memory_status.log
echo '------------' >> memory_status.log
/test/show_queue.sh
fi
sleep 60
done
A very simple way to do it is to use two scripts. One with the loop and one which does the killing task :
for (( ; ; ))
do
DoKillingTask
rc=$? # <- You get the return code of the script and decide what to do
done
If it continues to be killed, Mikel (in comment of your question) is right.

How to egrep variable-Unix shell script

I’m trying to validate input by using egrep and regex.Here is the line from script (c-shell):
echo $1 | egrep '^[0-9]+$'
if ($status == 0) then
set numvar = $1
else
echo "Invalid input"
exit 1
endif
If I pipe echo to egrep it works, but it also prints the variable on the screen, and this is something I don't need.
To simply suppress output you can redirect it to the null device.
echo $1 | egrep '^[0-9]+$' >/dev/null
if ($status == 0) then
set numvar = $1
else
echo "Invalid input"
exit 1
endif
You might also want to consider using the -c option to get the count of matches instead of using using the status.
Also, unless you are using csh, the status is stored in $? not in $status
grep has a -q option that suppresses output
So:
egrep -q '^[0-9]+$'
you can use awk
$ echo "1234" | awk '{print $1+0==$1?"ok":"not ok"}'
ok
$ echo "123d4" | awk '{print $1+0==$1?"ok":"not ok"}'
not ok

Resources