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
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.
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