Receiving conditional operator expected error in bash - bash

Please excuse this extremely inefficient script, I am new to shell scripting. I am receiving an error near the if clause in the function matchFS(). I have posted the error down below. Can anyone offer me some guidance?
#!/bin/bash
function matchFS() {
usage=$(df -h | tail -n +2 | awk '{print $5}' | sed 's/%//g')
usagearr=( $usage )
for i in "${usagearr[#]}"
do
if [[ $1 eq "${usagearr[$i]}" ]]; then
# print matching row from df -h
fi
done
}
usage=$(df -h | tail -n +2 | awk '{print $5}' | sed 's/%//g')
usagearr=( $usage )
len=${#usagearr[#]}
for (( i=0; i<$len; i++ )) # we have to use (( )) here to represent the c style for loop
do
if [ "${usagearr[$i]}" -gt "10" ]; then
matchFS ${usagearr[$i]}
fi
done
Error: line 13: conditional binary operator expected
line 13: syntax error near eq'
line 13: if [[ $1 eq "49 ]]; then'

If you look at help test you'll quickly realize that eq is not one of the choices. At least, not without adding something else to it.

#!/bin/bash
function matchFS() {
### duplicate definition, these are already known to the function.
usage=$(df -h | tail -n +2 | awk '{print $5}' | sed 's/%//g')
usagearr=( $usage )
### you probably did want to use another variable here,
### because the "i" is also shared with the caller
for i in "${usagearr[#]}"
do
### -eq instead of eq
if [[ $1 -eq "${usagearr[$i]}" ]]; then
### the if statement can not be empty
# print matching row from df -h
fi
done
}
usage=$(df -h | tail -n +2 | awk '{print $5}' | sed 's/%//g')
usagearr=( $usage )
len=${#usagearr[#]}
for (( i=0; i<$len; i++ )) # we have to use (( )) here to represent the c style for loop
do
if [ "${usagearr[$i]}" -gt "10" ]; then
matchFS ${usagearr[$i]}
fi
done

Related

bash: syntax error in while loop

so in a bash script, have a while loop that read lines from the outpt of some pippelined sort commands. i get an error: line 13: syntax error near unexpected token 'done'
line 13 is the last line, where the "done" and the pipeline is. my script:
#!/bin/bash
while read -a line; do
if [[ ${line[2]} < $1 ]]; then
continue
fi
if [[ $2 != -MM ]]; then
if [[ ${line[3]} = N ]]; then
continue
fi
fi
echo -n "${line[0]} "
echo ${line[1]}
done < <(sort -b rooms | sort -sk2 | sort -sk4 | sort -sk3)
tnx.
I would first try to write the date to temp so I can see what the sorting is doing by inspecting the temp file. Then read that in line by line.
#!/usr/bin/env bash
TMPF="/tmp/tmp-file.dat"
sort -b rooms | sort -sk2 | sort -sk4 | sort -sk3 > "${TMPF}"
while IFS= read -r line ;do
if [[ ${line[2]} -ge $1 ]] && [[ $2 != -MM ]] && [[ ${line[3]} = N ]]; then
echo -n "${line[0]} "
echo ${line[1]}
fi
done < "${TMPF}"
You can use without using ()
like done < rooms |sort -b | sort -sk2 | sort -sk4 | sort -sk3

execute mailx using shell script

I am trying to run the below script.
val = `wc -l /home/validate.bad | awk '{print $1}' | tail -n1`
valCount = `wc -l /home/validation.txt | awk '{print $1}'`
if [ "$val" -gt 1 ] && ["$valCount" -gt 1]
then
mailx -s "Validation failed" -r xyz#abc.com xyz#abc.com<<-EOF
Hi ,
Validation has failed. Please check.
EOF
elif [ "$valCount" -gt 1 ]
then
mailx -s "Validation pass" -r xyz#abc.com xyz#abc.com<<-EOF
Hi Team,
Validation success.
EOF
fi
But I am getting this error.
Error:
val: comand not found
valCount: command not found
line 3[: : integer expression expected
You can't have spaces around = :
val = `wc -l /home/validate.bad | awk '{print $1}' | t` # wrong
and should have been
val=`wc -l /home/validate.bad | awk '{print $1}' | t`
or preferrably
val=$(wc -l </home/validate.bad)
#`..` is legacy , $() supports nesting, one good reason to go for it
# You use awk and tail uselessly
Also
["$valCount" -gt 1]
should have been
[ "$valCount" -gt 1 ] # mind the spaces for the test constructie
# [spaceSTUFFspace] is the correct form
Sidenote
You may use [ shellcheck ] to check your scripts.

Converting multiple lines of bash in to a single line

Is there any short and easy way to convert multiple lines of script in to a single line to be parsed in a eval command?
ie
getent group | cut -f3 -d":" | sort -n | uniq -c |\
while read x ; do
[ -z "${x}" ] && break
set - $x ; if [ $1 -gt 1 ]; then
grps=`getent group | nawk -F: '($3 == n) { print $1 }' n=$2 | xargs` ; echo "Duplicate GID ($2): ${grps}" ; fi done
one_line=`cat your_script_file | sed ":a s/[\]$//; N; s/[\]$//; s/\n/ /; t a ;"`
echo $one_line

Bash ping output in csv format

My aim is to transform the output (the last 2 lines) of the ping command in a CSV style.
Here are some examples:
In case there is a packet loss lower than 100% <
URL, PacketLoss, Min, Average, Max, Deviation
In case there is packet loss equal to 100%
URL, 100, -1, -1, -1, -1
My script is below, but when the packet loss is 100% the output is:
URL, 100,
So the problem is at the if statement, as it does not enter in elif, I use the same syntax as checking if the address is full or not (with "www." or not).
Can you please have a look because I tried multiple things and it did not work.
My script:
#!/bin/bash
declare site=''
declare result='';
if [[ "$1" == "www."* ]]; then
site="$1";
else
site="www.$1";
fi
result="$site";
pingOutput=$(ping $site -c10 -i0.2 -q| tail -n2);
fl=true;
while IFS= read -r line
do
# !!! The problem is here, the if statement is not working properly and I do not know why !!!
if [ "$fl" == "true" ]; then
result="$result $(echo "$line" | cut -d',' -f3 | cut -d" " -f2 | sed -r 's/%//g')";
fl=false;
elif [[ "$line" == "ms"* ]]; then
result="$result $(echo "$line" | cut -d' ' -f4 | sed -r 's/\// /g')";
else
result="$result -1 -1 -1 -1";
fi
done <<< "$pingOutput"
echo "$result";
This is a pretty old question but I've just stumbled upon it today. Below I paste a slight modified version of the above script that fixes the if issue and works on Mac OS.
P.S. You can uncomment the # prctg=100.0% line to see the if working.
#!/bin/bash
declare site=''
declare result=''
declare prctg=''
[[ "$1" == "www."* ]] && site="$1" || site="www.$1"
result="$site"
pingOutput=$(ping $site -c10 -i0.2 -q | tail -n2)
fl=true
while IFS= read -r line
do
#echo $line
if [ "$fl" == "true" ]
then
prctg=$(echo "$line" | grep -Eo "[.[:digit:]]{1,10}%")
result="$result,$prctg"
fl=false
# prctg=100.0%
else
if [ "$prctg" == "100.0%" ]
then
result="$result,-1,-1,-1,-1"
else
result="$result,$(echo "$line" | cut -d' ' -f4 | sed -E 's/\//,/g')"
fi
fi
done <<< "$pingOutput"
echo "$result"
I hope it helps someone from the future! :)
Since the second line of the pingOutput was never processed (the loop ended before) the action of adding the -1 to the output was never performed.
Due to this problem I decided to capture the percentage of failure and act when no packets were returned (100%), I also simplified some expressions you used initially.
I investigated the script and came up with the following solution:
#!/bin/bash
declare site=''
declare result=''
declare prctg=''
[[ "$1" == "www."* ]] && site="$1" || site="www.$1"
result="$site"
pingOutput=$(ping $site -c10 -i0.2 -q| tail -n2)
fl=true
while IFS= read -r line
do
# !!! The problem is here, the if statement is not working properly and I do not know why !!!
echo $line
if [ "$fl" == "true" ]
then
prctg=$(echo "$line" | grep -Po "[0-9]{0,3}(?=%)")
result="$result $prctg"
fl=false
fi
if [ "$prctg" == "100" ]
then
result="$result -1 -1 -1 -1"
else
result="$result $(echo "$line" | cut -d' ' -f4 | sed -r 's/\// /g')"
fi
done <<< "$pingOutput"
echo "$result"

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