shell script: "'<<' unmatched"-syntax error using here document

13,847

The here string delimiter must not be indented, your END should be at the beginning of the line:

$ cat <<EOT
> foo
>         bar
> EOT
foo
        bar

If you want the trailing delimiter to be indented you can use the following syntax, but this will also strip all leading tabs from the here document itself (this only works with tabs!):

$ cat <<-EOT
>         foo
>         bar
>         quux
>         EOT
foo
bar
quux

Note that this behaviour is specified by POSIX so should work in all compliant shells:

If the redirection symbol is "<<-", all leading tabs shall be stripped from input lines and the line containing the trailing delimiter.

Share:
13,847

Related videos on Youtube

cogle
Author by

cogle

Updated on September 26, 2022

Comments

  • cogle
    cogle over 1 year

    Hi I am attempting to write a program that will alert the user if a person of interest has come online at a given time. My program thus far is

    #!/usr/bin/ksh
    message=""
    when=""
    validFiles=""
    validUsers=""
    
    if [ $# -gt 0 ] ; then
        while getopts w:m: opt
        do
            case $opt in
            w) when=$OPTARG;;
            m) message=$OPTARG;;
            \?) echo $USAGE exit 2;;
            esac
        done
        shift $(($OPTIND - 1))
        if [[ $# -gt 0 ]] ; then
            for i; do
                if [[ -f "$i" && -r "$i" ]]; then
                    if ! echo $validFiles | grep $i >/dev/null; then
                        validFiles="$validFiles $i"
                    fi
                elif id $i 2> /dev/null 1>&2; then
                    if ! echo $validUsers | grep $i > /dev/null; then
                        validUsers="$validUsers $i"
                    fi
                fi
            done
            if [[ $when != "" && $validFiles != "" || $validUsers != "" ]] ;then
                for i in $validUsers; do
                    if ! grep $i $validFiles >/dev/null; then
                        at $when <<"END"
                            if finger $i | grep $i; then
                                echo "$i is online" | elm $message
                            fi
                        END
                    fi
                done
            fi
        else
            echo "No files or usernames"
        fi
    else
        echo "No arguments provided"
    fi
    

    My problem is that when I attempt to run this I get the error message

     syntax error at line 33 : `<<' unmatched
    

    I am not sure as to why this is appearing. I have checked many other examples and my at command,here document, appears to be the same as theirs. Could anybody help me out? Thanks.

  • cogle
    cogle about 10 years
    Thanks! I just got that! is there anyway to have a delimiter in the call to the command itself? Like at (delimiter) <<EOT
  • Adrian Frühwirth
    Adrian Frühwirth about 10 years
    Not sure I understand your question, care to rephrase?
  • cogle
    cogle about 10 years
    So ok, I can't indent the command is there option that would cut out the excess whitespace for me?
  • Adrian Frühwirth
    Adrian Frühwirth about 10 years
    You can indent the here document content as much or little as you want, just the closing delimiter is not allowed to be indented (otherwise the parser wouldn't know where the here doc ends), which should not be a problem?
  • Adrian Frühwirth
    Adrian Frühwirth about 10 years
    I added some info about command <<-delimiter which you might find helpful, but note that this affects all lines and only works with tabs.
  • Emmet
    Emmet about 10 years
    @ChrisOgle: If an answer solves your problem, you should “accept” it by clicking the arrow outlined in green to the left of that answer. In this case, you don't have a difficult choice :)