Grep issues with if statement in shell script

6k Views Asked by At

I'm having an issue with tail & grep in shell script if statement. If I run tail -5 mylog.log | grep -c "Transferred: 0" in shell, it runs as it should, but in this shell script if statement:

# Parse log for results
if [ tail -1 "$LOGFILE" | grep -c "Failed" ] ; then
        RESULT=$(tail -1 "$LOGFILE")
elif [ tail -5 "$LOGFILE" | grep -c "Transferred:            0" ] ; then
        RESULT=""
else
        RESULT=$(tail -5 "$LOGFILE")
fi

I get

... [: missing `]'
grep: ]: No such file or directory

for both of the grep lines.

It's clearly to do with the closing ] being seen as part of the grep (and thus missing) but I'm using the correct whitespace so I can't figure out what's going on? What am I doing wrong here?

Thanks, PJ

1

There are 1 best solutions below

2
On BEST ANSWER

Immediate Issue / Immediate Fix

Take out the brackets.

if tail -1 "$logfile" | grep -q "Failed" ; then

[ is not part of if syntax. Rather, it's a synonym for the command named test (which is typically both available as a shell builtin and an external binary, like /bin/test or /usr/bin/test).

Thus, your original code was running [ tail -1 "$logfile", and piping its result to grep -q "Failed" ]. The first [ was failing because it didn't see an ending ] -- which is mandatory when invoked by that name rather than with the name test -- and also because its parameters weren't a test it knew how to parse; and the second grep didn't know what the ] it was being piped meant, trying to find a file by that name.


Other Notes

Try to run external commands -- like tail -- as little as possible. There's a very significant startup cost.

Consider the following, which runs tail only once:

#!/bin/bash
#      ^^^^- IMPORTANT: bash, not /bin/sh

last_5_lines="$(tail -5 "$logfile")"
last_line="${last_5_lines##*$'\n'}"
if [[ $last_line = *Failed* ]]; then
  result=$last_line
elif [[ $last_5_lines =~ 'Transferred:'[[:space:]]+'0' ]]; then
  result=''
else
  result=$last_5_lines
fi