I'm trying to find errors in log, and I need to send message if any number of error is greater than 0.
My script looks like this:
var1=$(grep Errors: rclone.log | awk '{print $2;}')
for i in "${var1}"
do
if [ "$i" -gt "0" ]; then
echo "Errors"
else
echo "No errors"
fi
done
Variable $i looks like this
0 2 1 0 0 0 10
But if I run my script, I'm always see errors like this:
./test.sh: line 7: [: 0
2
1
0
0
0
10: integer expression expected
So my idea, is to find all number in $i greater than 0. Where is my mistake?
My input file:
Checking:
Errors: 0
Checks: 741286 / 751291, 99%
Transferred: 2005 / 2005, 100%
Elapsed time: 39m26.2s
Checking:
Errors: 0
Checks: 741465 / 751470, 99%
Transferred: 2005 / 2005, 100%
Elapsed time: 39m26.7s
Checking:
Errors: 10
Checks: 741616 / 751621, 99%
Transferred: 2005 / 2005, 100%
Elapsed time: 39m27.2s
CodePudding user response:
The double quotes around ${var1}
cause the for
loop to only loop once, using the entire value of the variable as the sole value of $i
. So you end up comparing the string 0
(newline) 2
(newline) 1
etc against the number 0, which is not well-defined. See also When to wrap quotes around a shell variable?
The indirection via a variable seems superfluous, too. A minimal fix would look like
awk '/Errors:/ {print $2;}' rclone.log |
while read -r i
do
if [ "$i" -gt 0 ]; then
echo "Errors"
else
echo "No errors"
fi
done
This fixes the useless grep
but keeps the bug that it will print "No errors" every time there is a zero in the input, and "Errors" for every other result. I'm guessing you simply wanted to print something once, and that should be "Errors" if there was at least one non-zero result?
Anyway, if you are already using Awk, you are better off writing all of this in Awk.
awk '/Errors:/ { if($2>0) e }
END { print (e ? "Errors" : "No errors")
exit e>1 }' rclone.log
Notice also how this sets the exit code from Awk to produce a machine-readable result you can use directly in a script ... maybe something like
if awk ...>/dev/null; then
echo "$0: do panic!" >&2
fi