LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   syntax error: unexpected end of file (https://www.linuxquestions.org/questions/linux-newbie-8/syntax-error-unexpected-end-of-file-4175637551/)

jinlei 08-31-2018 07:50 PM

syntax error: unexpected end of file
 
Hopefully this is not a silly question. I am just repeating an example from the book <The Linux Command Line> Fourth Internet Edition by William Shotts. Taking the example on page 423, I always come across this problem. Can anyone help to figure it out?

Code:

#!/bin/bash
#Program to output a system information page
TITLE="System Information Report For $HOSTNAME"
CURRENT_TIME="$(date +"%x %r %Z")"
TIMESTAMP="Generated $CURRENT_TIME, by $USER"

report_home_space (){
    if [[ "$(id -u)" -eq 0 ]]; then
        cat <<- _EOF_
            <H2>Home Space Utilization (All Users)</H2>
            <PRE>$(du -sh /home/*)</PRE>
            _EOF_
    else
        cat <<- _EOF_
            <H2>Home Space Utilization ($USER)</H2>
            <PRE>$(du -sh $HOME)</PRE>
            _EOF_
    fi
    return
}

cat << _EOF_
<HTML>
    <HEAD>
        <TITLE>$TITLE</TITLE>
    </HEAD>
    <BODY>
            <H1>$TITLE</H1>
            <P>$TIMESTAMP</P>
            $(report_home_space)
    </BODY>
</HTML>
_EOF_

The problem is gone, if I shorten the above code as below:
Code:

#!/bin/bash
#Program to output a system information page
TITLE="System Information Report For $HOSTNAME"
CURRENT_TIME="$(date +"%x %r %Z")"
TIMESTAMP="Generated $CURRENT_TIME, by $USER"

report_home_space (){
    echo "Function report_home_space executed."
    return
}

cat << _EOF_
<HTML>
    <HEAD>
        <TITLE>$TITLE</TITLE>
    </HEAD>
    <BODY>
            <H1>$TITLE</H1>
            <P>$TIMESTAMP</P>
            $(report_home_space)
    </BODY>
</HTML>
_EOF_

To me, the only difference between the two pieces of codes is: there are two extra pairs of "_EOF_" in the first piece. But I might miss something obvious. Thank you!

scasey 09-01-2018 01:34 PM

Code:

cat <<- _EOF_
What is that hyphen doing there in the first two cat statements?

Use set -x to see what bash is doing...
Code:

#!/bin/bash
#Program to output a system information page
set -x
...


michaelk 09-01-2018 01:42 PM

The eof has to at the beginning of the line. No spaces.

MadeInGermany 09-01-2018 02:45 PM

I think the - allows leading TABs.
And I think that characters ( and ) need to be escaped in order to satisfy the parser:
\(All Users\) and \($USER\)

scasey 09-01-2018 03:09 PM

Quote:

Originally Posted by MadeInGermany (Post 5898779)
I think the - allows leading TABs.

I see that is true...did not know that. From man bash -- Here Documents section:
Code:

If the redirection operator is <<-, then all leading tab characters are stripped from input lines and the line containing delimiter.  This allows here-documents within shell scripts to be indented in a natural fashion.
...so that should allow the not-left-flush ending _EOF_ to work IF the leading whitespace is tab(s), but apparently not if it is spaces...

That said, I'm pretty sure that there should be no spaces between the << or <<- and the word (in this case the word is _EOF_, but it can be any string). Try removing the space there.

(confirmed...setting the leading spaces to tabs still threw the error. Removing the space after the << and <<- allowed the script to run.)

jinlei 09-01-2018 03:44 PM

Quote:

Originally Posted by michaelk (Post 5898755)
The eof has to at the beginning of the line. No spaces.

Thank you very much! It works! Accurately, only the second "_EOF_" within each pair must stay at the beginning of a new line. The codes below works:

Code:

#!/bin/bash
#Program to output a system information page
TITLE="System Information Report For $HOSTNAME"
CURRENT_TIME="$(date +"%x %r %Z")"
TIMESTAMP="Generated $CURRENT_TIME, by $USER"

report_home_space (){
    if [[ "$(id -u)" -eq 0 ]]; then
        cat <<- _EOF_
            <H2>Home Space Utilization (All Users)</H2>
            <PRE>$(du -sh /home/*)</PRE>
_EOF_
    else
        cat <<- _EOF_
            <H2>Home Space Utilization ($USER)</H2>
            <PRE>$(du -sh $HOME)</PRE>
_EOF_
    fi
    return
}

cat << _EOF_
<HTML>
    <HEAD>
        <TITLE>$TITLE</TITLE>
    </HEAD>
    <BODY>
            <H1>$TITLE</H1>
            <P>$TIMESTAMP</P>
            $(report_home_space)
    </BODY>
</HTML>
_EOF_


jinlei 09-01-2018 03:49 PM

Quote:

Originally Posted by scasey (Post 5898790)
I see that is true...did not know that. From man bash -- Here Documents section:
Code:

If the redirection operator is <<-, then all leading tab characters are stripped from input lines and the line containing delimiter.  This allows here-documents within shell scripts to be indented in a natural fashion.
...so that should allow the not-left-flush ending _EOF_ to work IF the leading whitespace is tab(s), but apparently not if it is spaces...

That said, I'm pretty sure that there should be no spaces between the << or <<- and the word (in this case the word is _EOF_, but it can be any string). Try removing the space there.

(confirmed...setting the leading spaces to tabs still threw the error. Removing the space after the << and <<- allowed the script to run.)

Thank you! You are also right. After I changed spaces as tabs, everything works.


All times are GMT -5. The time now is 08:23 AM.