bash here-document 给出了“意外的文件结尾”错误
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18660798/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
here-document gives 'unexpected end of file' error
提问by thnkwthprtls
I need my script to send an email from terminal. Based on what I've seen here and many other places online, I formatted it like this:
我需要我的脚本从终端发送电子邮件。根据我在这里和网上许多其他地方看到的内容,我将其格式化为:
/var/mail -s "$SUBJECT" "$EMAIL" << EOF
Here's a line of my message!
And here's another line!
Last line of the message here!
EOF
However, when I run this I get this warning:
但是,当我运行它时,我收到此警告:
myfile.sh: line x: warning: here-document at line y delimited by end-of-file (wanted 'EOF')
myfile.sh: line x+1: syntax error: unexpected end of file
...where line x is the last written line of code in the program, and line y is the line with /var/mail
in it. I've tried replacing EOF
with other things (ENDOFMESSAGE
, FINISH
, etc.) but to no avail. Nearly everything I've found online has it done this way, and I'm really new at bash so I'm having a hard time figuring it out on my own. Could anyone offer any help?
...其中第 x 行是程序中最后编写的代码行,第 y 行是其中的行/var/mail
。我试着更换EOF
其他的事情(ENDOFMESSAGE
,FINISH
,等),但无济于事。我在网上找到的几乎所有东西都是这样做的,而且我对 bash 真的很陌生,所以我很难自己弄清楚。任何人都可以提供任何帮助吗?
回答by Barmar
The EOF
token must be at the beginning of the line, you can't indent it along with the block of code it goes with.
该EOF
令牌必须是在该行的开头,您不能使用的代码它会与块一起缩进它。
If you write <<-EOF
you may indent it, but it must be indented with Tabcharacters, not spaces. So it still might not end up even with the block of code.
如果你写<<-EOF
你可以缩进它,但它必须用Tab字符缩进,而不是空格。因此,即使使用代码块,它也可能不会结束。
Also make sure you have no whitespace afterthe EOF
token on the line.
另外,还要确保你有没有空格后的EOF
标记就行了。
回答by Joni
The line that starts or ends the here-doc probably has some non-printable or whitespace characters (for example, carriage return) which means that the second "EOF" does not match the first, and doesn't end the here-doc like it should. This is a very common error, and difficult to detect with just a text editor. You can make non-printable characters visible for example with cat
:
开始或结束 here-doc 的行可能有一些不可打印或空白字符(例如,回车),这意味着第二个“EOF”与第一个不匹配,并且不会像这样结束 here-doc这应该。这是一个非常常见的错误,仅使用文本编辑器很难检测到。您可以使不可打印的字符可见,例如cat
:
cat -A myfile.sh
Once you see the output from cat -A
the solution will be obvious: remove the offending characters.
一旦你看到cat -A
解决方案的输出就会很明显:删除有问题的字符。
回答by Rahul Tripathi
Please try to remove the preceeding spaces before EOF
:-
请尝试删除前面的空格EOF
:-
/var/mail -s "$SUBJECT" "$EMAIL" <<-EOF
Using <tab>
instead of <spaces>
for ident AND using <<-EOF works fine.
使用<tab>
代替<spaces>
for ident 和使用 <<-EOF 工作正常。
The "-"
removes the <tabs>
, not <spaces>
, but at least this works.
该"-"
删除<tabs>
,不是<spaces>
,但至少这个作品。
回答by Roel Van de Paar
Note one can also get this error if you do this;
请注意,如果您这样做,也可能会出现此错误;
while read line; do
echo $line
done << somefile
Because << somefile
should read < somefile
in this case.
因为在这种情况下<< somefile
应该阅读< somefile
。
回答by psychoslave
Here is a flexible way to do deal with multiple indented lines withoutusing heredoc.
这是一种不使用heredoc处理多个缩进行的灵活方法。
echo 'Hello!'
sed -e 's:^\s*::' < <(echo '
Some indented text here.
Some indented text here.
')
if [[ true ]]; then
sed -e 's:^\s\{4,4\}::' < <(echo '
Some indented text here.
Some extra indented text here.
Some indented text here.
')
fi
Some notes on this solution:
关于此解决方案的一些说明:
- if the content is expected to have simple quotes, either escape them using
\
or replace the string delimiters with double quotes. In the latter case, be careful that construction like$(command)
will be interpreted. If the string contains both simple and double quotes, you'll have to escape at least of kind. - the given example print a trailing empty line, there are numerous way to get rid of it, not included here to keep the proposal to a minimum clutter
- the flexibility comes from the ease with which you can control how much leading space should stay or go, provided that you know some sed REGEXP of course.
- 如果预期内容有简单的引号,请使用转义它们
\
或用双引号替换字符串分隔符。在后一种情况下,请注意结构 like$(command)
将被解释。如果字符串同时包含单引号和双引号,则必须至少以某种方式进行转义。 - 给定的例子打印一个尾随空行,有很多方法可以摆脱它,这里不包括在内,以将建议保持在最低限度的混乱
- 灵活性来自您可以轻松控制应该保留或离开多少领先空间,当然前提是您知道一些 sed REGEXP。
回答by YOLO ROFL
Along with the other answers mentioned by Barmar and Joni, I've noticed that I sometimes have to leave a blank line before and after my EOF when using <<-EOF
.
除了 Barmar 和 Joni 提到的其他答案外,我注意到有时在使用<<-EOF
.