IF section problem. syntax error: unexpected end of file error

Hello,

I have another problem with my script. Please accept my apologies, but I am really nooby in sh scripts. I am writing it for first time.

My script:

returned=`tail -50 SapLogs.log | grep -i "Error"`
echo $returned
if [ -n "${returned}" ]; then
    echo "There is no errors in the logs"
fi

And after execution of this script the error message appears:
checklogs.sh: line 11: syntax error: unexpected end of file.

When I delete this section, my script works good.

Thanks a lot for You outstanding help.

Regards,
Adrian

It is always scary when you get a syntax error on line 11 of a 5 line script.

My first comment would be that you should change:

echo $returned

to:

echo "$returned"

or better yet (removing problems that could be caused depending on the contents of SapLogs.log ):

printf '%s\n' "$returned"

But that alone isn't likely to be your problem. Maybe if you showed us the whole script and told us what OS and shell you're using, we'd have a better chance of figuring out what is going on.

Hello,

Thanks for prompt reply! Appreciate that.
Please find below whole script:

#!/bin/bash
echo "=== Checking logs ==="
returned=`tail -50 SapLogs.log | grep -i "Error"`
echo $returned
if [ -n "${returned}" ]; then
    echo "There is no error in the logfile"
fi
echo "=== Last log entry ==="
var=$(tail -1 SapLogs.log | awk '{print substr($0,13,8)}')
echo "Time elapsed since last entry =" $(( $((`date +%s -d $var`)) - $((`date +%s`)) ))

It returns output:

2014 Jul 28 12:27:47:444 GMT +2 SapLogFile Error [Adapter] AER3-000430 Total requests processed for operation RFC_READ_TEXT : 1945087
checklogs.sh: line 11: syntax error: unexpected end of file

But, what is more interesting, the script:

#!/bin/bash
echo "=== Checking logs ==="
returned=`tail -50 SapLogs.log | grep -i "Error"`
echo $returned
echo "=== Last log entry ==="
var=$(tail -1 SapLogs.log | awk '{print substr($0,13,8)}')
echo "Time elapsed since last entry =" $(( $((`date +%s -d $var`)) - $((`date +%s`)) ))

Works perfectly. It returns whole data:

=== Checking logs ===
2014 Jul 28 12:27:47:444 GMT +2 SapLogFile  Error [Adapter] AER3-000430 Total requests processed for operation RFC_READ_TEXT : 1945087
=== Last log entry ===
Time elapsed since last entry = -13490

Unfortunately I don't know how can I check what system I am using.

Regards,
Adrian Jedrzejewski

The command uname -a will tell you what version of what OS you're using.

It is very strange that the output from the 1st script you showed us did not contain the line:

=== Checking logs ===

Please add the following line to your script between the 1st and 2nd lines:

set -xv

and show us the output.

I don't see why the following would make any difference in the behavior of your script (except that if there are multiple errors found, they will be printed on separate lines; and a little bit of truth in advertising), but it will use less memory and run faster. Try changing:

returned=`tail -50 SapLogs.log | grep -i "Error"`
echo $returned
if [ -n "${returned}" ]; then
    echo "There is no error in the logfile"
fi

to:

tail -50 SapLogs.log | grep -i "Error"
if [ $? ]; then
    echo "There is no error in the last 50 lines in the logfile"
fi

My OS version:

Linux hostname 2.6.18-128.1.10.el5 #1 SMP Wed Apr 29 13:53:08 EDT 2009 x86_64 x86_64 x86_64 GNU/Linux

Unfortunately, it still doesn't work... I am confused a bit now :confused:
When I add set -xv to script the error appears:

: invalid optionne 2: set: -
set: usage: set [--abefhkmnptuvxBCHP] [-o option] [arg ...]

My current code is as follows (I've changed filename but content is the same):

#!/bin/bash
set -xv
echo "=== Checking logs ==="
tail -50 SapAdapterInboundRfc-P30-SapAdapterInboundSynchronous.log | grep -i "Error"
if [ $? ]; then
    echo "There is no error in the last 50 lines in the logfile"
fi
echo "=== Last log entry ==="
var=$(tail -1 SapAdapterInboundRfc-P30-SapAdapterInboundSynchronous.log | awk '{print substr($0,13,8)}')
echo "Time elapsed since last entry =" $(( $((`date +%s -d $var`)) - $((`date +%s`)) ))

When I delete set -xv the output is:

=== Checking logs ===
checklogs.sh: line 10: syntax error: unexpected end of file

I really don't know why this simply IF doesn't work...

Regards,
Adrian

I don't think you can just dump a raw number into [ ] like that without telling it what to do with that number. [ "$?" -ne 0 ] or such.

But if you just want to use the return value, do so directly. The ! reverses it to 'if not':

if ! tail -50 SapAdapterInboundRfc-P30-SapAdapterInboundSynchronous.log | grep -i "Error" >/dev/null
then
        echo "There is no error in the last 50 lines in the logfile"
fi
1 Like

Coronna688,
Ouch. Yes, you're correct. In shell's test , [ "$arg" ] tests for non-empty string; not non-zero and non-empty (as in awk ).

For clarity when reading a script, I don't usually use:

if ! tail -50 SapAdapterInboundRfc-P30-SapAdapterInboundSynchronous.log | grep -i "Error" >/dev/null

when the compound-list is more than about 40 characters long, but that is just my personal preference. We don't want the > /dev/null here because this code is replacing earlier code that was:

returned=`tail -50 SapLogs.log | grep -i "Error"`
echo $returned

and then checking whether "$returned " expands to an empty string.

And, now for the good news...
jedzio,
Know that we know you're using bash on a Linux distro (even though it hasn't been updated for four years), I think I know what the problem is. I should have asked what editor you were using!

To get that error message from bash for the command: set -xv , you must be using an editor that uses the DOS convention of carriage-return followed by newline as the line terminator instead of the UNIX/Linux convention using only the newline.

So, I think you can get your script to work if you write this into a new file (let's call it newscript ):

#!/bin/bash
echo "=== Checking logs ==="
tail -50 SapAdapterInboundRfc-P30-SapAdapterInboundSynchronous.log | grep -i "Error"
if [ $? -ne 0 ]; then
    echo "There is no error in the last 50 lines in the logfile"
fi
echo "=== Last log entry ==="
var=$(tail -1 SapAdapterInboundRfc-P30-SapAdapterInboundSynchronous.log | awk '{print substr($0,13,8)}')
echo "Time elapsed since last entry =" $(( $((`date +%s -d $var`)) - $((`date +%s`)) ))

and then run the commands:

tr -d '\r' < newscript > checklogs.sh
chmod +x checklogs.sh

to remove any extraneous carriage return characters in your script and make it executable again.

Let us know what happens.

We usually only see this problem on files that have been copied from Windows systems to UNIX and Linux systems. I strongly suggest that you look at the documentation for your editor to see if there is a way to set the characters used as line terminators. If there isn't any way to set the line terminator to just a newline (AKA linefeed) character, seriously consider learning how to use vi or emacs instead of your current editor. Extraneous carriage returns in shell scripts, source code for other languages, and in data files will cause you no end of grief.

That filename is a mouthful, yes. I'd put it in a variable :slight_smile:

What if we make use of grep's return value?

tail -50 SapLogs.log | grep -iq "Error"
if [ $? -eq 0 ]; then
  echo found error
else
 echo no error
fi

less code, avoid subshell invocation?

The original script didn't produce "found error"; it listed the error(s) found. To duplicate that behavior this way would be:

tail -50 SapLogs.log | grep -iq "Error"
if [ $? -eq 0 ]; then
  tail -50 SapLogs.log | grep -i "Error"
else
 echo no error
fi

The suggestions Corona688 (as long as we drop the >/dev/null) and I posted avoid the subshell and also avoid duplicating calls to tail and grep .

Oh God!
Thank You both for help! Yes, You are right, I am using notepad++, but in the Windows convention instead of Unix... How stupid I am. I've changed the convention to Unix type and my script works as hell!

From today You are my Unix Gods.

Regards,
Adrian Jdrzejewski

1 Like