If or while loop inside case command positional parameters - bash

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.

Related

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 =

UNIX shell scripting if and grep command

currently I'm working on a code :
egrep '("$1"|"$2")' Cities.txt > test.txt
if [ $# -eq 1] && grep -q "$1" test.txt ; then
grep $1 Cities.txt
elif [ $# -eq 2 ] && egrep -q '("$1"|"$2")' test.txt ; then
egrep '("$1"|"$2")' Cities.txt > $2.txt
else $1 not found on Cities.txt
fi
exit
basically, it lets user to enter 1 or 2 arguments and the argument(s) is/are used as a grep pattern in Cities.txt and redirect the output to a file named test.txt
If the user entered 1 argument and the argument matched the content of the test.txt , then it display the lines that contain argument 1 on file Cities.txt.
If the user entered 2 argument and both argument matched the content of the file test.txt, then it matched both argument in Cities.txt and redirect the output to the file named by the user's second argument.
I couldn't seem to get the code to work, may be some of you guys could help me inspect the error.
thanks
egrep "($1|$2)" Cities.txt > test.txt # change single quote to double quote
if [ $# -eq 1 ] && grep -q -- "$1" test.txt ; then
grep -- "$1" Cities.txt
elif [ $# -eq 2 ] && egrep -q -- "($1|$2)" test.txt ; then
egrep -- "($1|$2)" Cities.txt > $2.txt
else
$1 not found on Cities.txt
fi
This greatly changes the semantics, but I believe is what you are trying to do. I've added -- to try to make this slightly robust, but if either argument contains metacharacters for the regex this will fail. But you could try:
if test $# -eq 1 && grep -F -q -e "$1" test.txt ; then
grep -F -e "$1" Cities.txt
elif [ $# -eq 2 ] && grep -q -F -e "$1" -e "$2" test.txt; then
grep -F -e "$1" -e "$2" Cities.txt > $2.txt
else
$1 not found on Cities.txt >&2
fi

Grep inside bash script not finding item

I have a script which is checking a key in one file against a key in another to see if it exists in both. However in the script the grep never returns anything has been found but on the command line it does.
#!/bin/bash
# First arg is the csv file of repo keys separated by line and in
# this manner 'customername,REPOKEY'
# Second arg is the log file to search through
log_file=$2
csv_file=$1
while read line;
do
customer=`echo "$line" | cut -d ',' -f 1`
repo_key=`echo "$line" | cut -d ',' -f 2`
if [ `grep "$repo_key" $log_file` ]; then
echo "1"
else
echo "0"
fi
done < $csv_file
The CSV file is formatted as follows:
customername,REPOKEY
and the log file is as follows:
REPOKEY
REPOKEY
REPOKEY
etc
I call the script by doing ./script csvfile.csv logfile.txt
Rather then checking output of grep command use grep -q to check its return status:
if grep -q "$repo_key" "$log_file"; then
echo "1"
else
echo "0"
fi
Also your script can be simplified to:
log_file=$2
csv_file=$1
while IFS=, read -r customer repo_key; do
if grep -q "$repo_key" "$log_file"; then
echo "1"
else
echo "0"
fi
done < "$csv_file"
use the exit status of the grep command to print 1 or 0
repo_key=`echo "$line" | cut -d ',' -f 2`
grep -q "$repo_key" $log_file
if [ $? -eq 1 ]; then
echo "1"
else
echo "0"
fi
-q supresses the output so that no output is printed
$? is the exit status of grep command 1 on successfull match and 0 on unsuccessfull
you can have a much simpler version as
grep -q "$repo_key" $log_file
echo $?
which will produce the same output

call a function in if statement returns nothing

can anyone please help me with the following script why usage function is not returning its value when called in if statement, it returns nothing on executing the script
#! /bin/bash
function usage()
{
echo "Please enter a valid process name that is currently running after the execution command"
}
if [ `echo $(ps -ef) | grep -c "$1"` -eq 0 ] then
**usage**
elif [ `echo $(ps -ef) | grep -c "$1"` -gt 0 ] then
Path=`ps -ef | grep "$1" | grep -v "grep" | awk '{print $2}'`
echo "$Path"
fi
Your first and second if/elif conditions are not being met. Therefore the script returns no value.
You can test by adding a final if statement that just echoes "No conditions met".

bash script and greping with command line

new to bash scripting so just wondering if i am doing this code right at all. im trying to search /etc/passwd and then grep and print users.
usage ()
{
echo "usage: ./file.sk user"
}
# test if we have two arguments on the command line
if [ $# != 1 ]
then
usage
exit
fi
if [[ $# < 0 ]];then
usage
exit
fi
# Search for user
fullname=`grep $1 /etc/passwd | cut -f 5 -d :`
firstname=`grep $1 /etc/passwd | cut -f 5 -d : | cut -f 1 -d " "`
#check if there. if name is founf: print msg and line entry
not sure as how to this or if im doing this right...
am i doing this right?
grep $1 /etc/passwd | while IFS=: read -r username passwd uid gid info home shell
do
echo $username: $info
done
This might work for you:
fullname=$(awk -F: '/'$1'/{print $5}' /etc/passwd)
firstname=${fullname/ *}
You're on the right track.
But I think the 2nd if [[ $# < 0 ]] .... fi block doesn't get you much. Your first test case gets the situation right, 'This script requires 1 argument or quits'.
Also, I don't see what you need firstname for, so a basic test is
case "${fullname:--1}" in
-[1] ) printf "No userID found for input=$1\n" ; exit 1 ;;
* )
# assume it is OK
# do what every you want after this case block
;;
esac
You can of course, duplicate this using "${firstname}" if you really need the check.
OR as an equivalent if ... fi is
if [[ "${fullname}" == "" ]] ; then
printf "No userID found for input=$1\n" ; exit 1
fi
note to be more efficient, you can parse ${fullname} to get firstname without all the calls to grep etc, i.e.
firstname=${fullname%% *}
Let me know if you need for me to explain :--1} and %% *} variable modifiers.
I hope this helps.
Instead of this:
fullname=`grep $1 /etc/passwd | cut -f 5 -d :`
firstname=`grep $1 /etc/passwd | cut -f 5 -d : | cut -f 1 -d " "`
Try this:
fullname=$(cut -f5 -d: /etc/passwd | grep "$1")
if [[ $? -ne 0 ]]; then
# not found, do something
fi
firstname=${fullname%% *} # remove the space and everything after
Note that I changed my answer to cut before grep so that it doesn't get false positives if some other field matches the full name you are searching for.
You can simply by reading your input to an array and then printing out your desired fields, something like this -
grep $1 /etc/passwd | while IFS=: read -a arry; do
echo ${arry[0]}:${arry[4]};
done
Test:
jaypal:~/Temp] echo "root:*:0:0:System Administrator:/var/root:/bin/sh" |
while IFS=: read -a arry; do
echo ${arry[0]}:${arry[4]};
done
root:System Administrator

Resources