0

I have the following block of code in my file:

175 MY_IP=`ifconfig eno1 | grep netmask | tr -s ' ' | cut -d " " -f 3`  
176 echo ""  > /home/hadoop/.ssh/config  
177 cat > /home/hadoop/.ssh/config  <<EOF  
178 Host `echo $MY_IP | sed 's/.[0-9][0-9]*$//g'`.* 0.0.0.0 master   worker*  
179    StrictHostKeyChecking no  
180    UserKnownHostsFile=/dev/null  
181 EOF  

I expect lines 178 to 181 to just be written to a file, but I get this error output:

/script.sh: line 178: unexpected EOF while looking for matching `''
/script.sh: line 184: syntax error: unexpected end of file

Why is it not just copying that text instead of checking its syntax?

Update: The way my code and error messages look right now:

175 MY_IP=`ifconfig eno1 | grep netmask | tr -s ' ' | cut -d " " -f 3`  
176 echo ""  > /home/hadoop/.ssh/config  
177 cat > /home/hadoop/.ssh/config  <<EOF  
178 Host `echo $MY_IP | sed "s/.[0-9][0-9]*$//g"`.* 0.0.0.0 master worker*  
179    StrictHostKeyChecking no  
180    UserKnownHostsFile=/dev/null  
181 EOF  
182   
183 chown -R hadoop:hadoop /home/hadoop  

/script.sh: line 175: unexpected EOF while looking for matching `''
/script.sh: line 184: syntax error: unexpected end of file

Solved: After reviewing my code, I found a missing single quote in one of the very first lines. Pairing it with another solved the issue.

  • 1
    the code you posted does not generate those error messages; they're only generated if you leave out one of the single quotes from the sed command ('s/..//g') – mosvy Mar 11 at 20:54
  • I don't expect the error either but I am getting it 100% :) Using the code just like it is in my 2nd example above. – Steve Mar 11 at 21:33
  • Steve I still cannot reproduce your error message. Unless @mosvy can spot the issue, would it be possible for you to post to actual script that you are running online (at pastebin.com or similar)? There may be some issue with encoding or the prior lines that we can't see here. – John1024 Mar 11 at 21:40
  • 1
    the only possibility left is that there's an unclosed quote somewhere before line 175, as explained in @ilkkachu's answer. – mosvy Mar 11 at 21:59
  • Thanks Mosvy that was it! A single quote without a partner at the very top of my doc. – Steve Mar 12 at 13:47
2

The shell will perform different kind of expansions (including command substitutions like your `echo ...`, but also variable and arithmetic expansions) inside here documents unless the delimiter is quoted.

Compare:

cat <<EOF
$$ $((2 + 3)) $(hostname) `date`
EOF
4502 5 fazq Mon Mar 11 23:03:27 EET 2019

vs:

cat <<'EOF'
$$ $((2 + 3)) $(hostname) `date`
EOF
$$ $((2 + 3)) $(hostname) `date`

Both double or single quotes will do in the last case.

  • I tried the quotes but unfortunately my error is still the same. – Steve Mar 11 at 21:17
  • 1
    please edit your question with the exact code and error message; as it stands, the code and error message do not match. – mosvy Mar 11 at 21:20
  • Thank you, I've edited the question. – Steve Mar 11 at 21:30
1

From man bash:

Here Documents
This type of redirection instructs the shell to read input from the current source until a line containing only delimiter (with no trailing blanks) is seen. All of the lines read up to that point are then used as the standard input (or file descriptor n if n is specified) for a command.

Your EOF line, as currently posted in the question, contains trailing blanks. Remove them.

  • in that case, bash will keep reading until the end of file and only generate a warning, with a different message "here-document at line N delimited by end-of-file". – mosvy Mar 11 at 20:57
  • @mosvy If I use the OP's code as posted (but minus the line numbers), I get warning: here-document at line 3 delimited by end-of-file (wanted `EOF'). If I remove the trailing blanks, bash -n script.sh generates no warnings. Do you see something different? (Yes, I know that the quoted message is inconsistent with that but this wouldn't be the first time on SE that the quoted code and error message are inconsistent.) – John1024 Mar 11 at 21:05
  • No, they have just corrected the code before posting it ;-) – mosvy Mar 11 at 21:09
  • Thank you for your response, unfortunately my file does not actually contain the trailing spaces after EOF. – Steve Mar 11 at 21:18
  • @Steve After I replace EOF (with, as posted, the two trailing spaces) with EOF (no trailing space) in the posted code, it generates no errors or warnings. If you are still getting an error, please document it carefully and add an update to the question. – John1024 Mar 11 at 21:23
1

We don't have the whole script here, but note how the line number on the "unexpected EOF while looking for matching [single quote]" changes from 178 to 175 when you change the quotes inside the here-doc from single quotes to double quotes.

That hints to me that the actual issue, the unfinished quote, is somewhere before the snippet you posted.

For example, in the script below the actual error is obviously on the first line, but from the shell's point of view, the quoted string started there continues until the next quote, and so on, with the unpaired one being the one after bar (note how the syntax highlighting makes it evident that the second echo is quoted and foo and bar aren't):

$ cat quote.sh
echo 'error here

echo 'foo' 'bar'
$ bash quote.sh
quote.sh: line 3: unexpected EOF while looking for matching `''
quote.sh: line 4: syntax error: unexpected end of file

Changing the second echo command to echo "foo" "bar" would show the error on line 1, as that would then be the line where the final single-quoted string starts.

You'll need to look through your whole script more closely. Or just dump it to shellcheck.net, it will notice cases like this.

  • After reviewing my code, I found a missing single quote in one of the very first lines. It runs now. Thanks! – Steve Mar 12 at 13:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.