Bash语法错误:文件意外结束


99

原谅我,这是Bash中非常简单的脚本。这是代码:

#!/bin/bash
# june 2011

if [ $# -lt 3 -o $# -gt 3 ]; then
   echo "Error... Usage: $0 host database username"
   exit 0
fi

运行sh file.sh之后:

语法错误:文件意外结束

Answers:


137

我认为file.sh与CRLF行终止符一起使用。

dos2unix file.sh

然后问题将得到解决。

您可以使用以下方法在ubuntu中安装dos2unix:

sudo apt-get install dos2unix

这个问题背后的原因是什么?我通常在Windows上工作,但需要将脚本传输到UNIX系统。
CMCDragonkai 2013年

Windows中的换行符是“ \ r \ n”,而Linux中的换行符是“ \ n”。
clyfish

8
@KeesdeKooter我不会说仅仅是因为某些对您无效的事情,您应该对其进行降票,很明显,这对28个投票都是有效的。一个简单的对我来说不起作用就足够了。这就是为什么SO允许一个问题有多个答案,因为一个问题可以有多个解决方案。
杰夫·威尔伯特

2
使用记事本++编辑器“编辑”>“ EOL转换”>“旧Mac格式”为我解决了该问题。
raktale

如果可以使用Notepad ++编辑bash文件。转到编辑-> EOL转换-> Macintosh(CR)。即使使用Windows操作系统,也将其更改为Macintosh(CR)。
Juniar

127

要检查的另一件事(只是在我身上发生):

  • 用分号终止单行函数的主体

即,这个看起来很无辜的代码段将导致相同的错误:

die () { test -n "$@" && echo "$@"; exit 1 }

使愚蠢的解析器高兴:

die () { test -n "$@" && echo "$@"; exit 1; }

3
+1也适用于带有方括号的代码段,例如:[[“ $#” == 1]] && [[“ $ arg” == [1,2,3,4]]] && printf“%s \ n ““等等” || {printf“%s \ n”“等等”;用法; } ............请注意,在调用了一些先前定义的函数“用法”之后,在方括号内的分号。忘记这将使您获得相同的语法错误:意外的eof。
Cbhihe

你钉了它。实际上,最简单的事情是,;每条语句的结尾都应该;这样结尾,例如:if [ -f ~/.git-completion.bash ]; then . ~/.git-completion.bash fi将产生该错误,而if [ -f ~/.git-completion.bash ]; then . ~/.git-completion.bash; fi;不会...注意结尾处的小分号,即:之后.bashfi
伊曼纽尔·马哈尼

1
我在一个与zsh用户共享的脚本中使用了此脚本。前者做工作zsh,但不是sh也不bash。希望我是4个人,所以我可以给这4个人投票
Davos

42

通过在if子句中使用错误的语法,我也刚收到此错误消息

  • else if (语法错误:文件意外结束)
  • elif (正确的语法)

我通过注释掉调试它直到工作


太谢谢你了..有人请给这个家伙一块奖牌
Happiehappie

17

一个未关闭的if => fi子句也会引起这个问题

提示:如果脚本很大,请使用陷阱进行调试...

例如

set -x
trap read debug

1
我完全忘记了“ fi”!谢谢:)如果可以的话,为了所有人的利益,请在使用陷阱的技巧上进行一些详细说明。
卡尔斯·阿尔科里亚

3
抱歉,抱歉,我的朋友。'trap'命令是一种通过在每一行之后基本中断来调试脚本的方法。更全面的讨论在这里:stackoverflow.com/questions/9080431/…–
theRiley

1
非常有用,非常感谢。请注意,点击unexpected end of file后将立即发生错误fi
StephaneB。18年

8

我从StackOverflow上的类似问题得到了这个答案

在Vim中打开文件,然后尝试

:set fileformat=unix

将eh行尾转换为Unix尾声,看看是否可以解决问题。如果在Vim中编辑,请输入命令:set fileformat = unix并保存文件。其他几种编辑器也可以转换行尾,例如Notepad ++或Atom

谢谢@lemongrassnginger


这些只是dos2unix接受的答案所建议的替代方法。
ulidtko

7

在cygwin上,我需要:-

 export SHELLOPTS
 set -o igncr

在.bash_profile中。这样我就不需要运行unix2dos


6

所以我找到了这篇文章,答案并没有帮助我,但是我能够弄清楚为什么它给了我错误。我曾有一个

cat > temp.txt < EOF
some content
EOF

问题是我将上面的代码复制到了函数中,并在不经意间选中了代码。需要确保未选中最后一个EOF。


1
这正是我的情况。我EOF缩进了四个空格,因此bash不能解析它。删除空格可解决此问题。
aexl

5

我在一行中编写“ if-fi”语句时遇到了问题:

if [ -f ~/.git-completion.bash ]; then . ~/.git-completion.bash fi

写多行解决了我的问题:

if [ -f ~/.git-completion.bash ]; then 
    . ~/.git-completion.bash
 fi

3

当我尝试使用parens调用函数时,例如这发生在我身上

run() {
  echo hello
}

run()

应该:

run() {
  echo hello
}

run

2

对于Windows:

就我而言,我在Windows OS上工作,并且在运行autoconf时遇到相同的错误。

  • 我只是使用NOTEPAD ++ IDE 打开configure.ac文件。
  • 然后,我通过EOL转换将文件转换为Windows(CR LF),如下所示:

    编辑-> EOL转换-> Windows(CR LF)


1

我能够将您的代码剪切并粘贴到文件中,并且可以正确运行。如果像这样执行它,它应该可以工作:

您的“ file.sh”:

#!/bin/bash
# june 2011

if [ $# -lt 3 -o $# -gt 3 ]; then
   echo "Error... Usage: $0 host database username"
   exit 0
fi

命令:

$ ./file.sh arg1 arg2 arg3

请注意,“ file.sh”必须是可执行的:

$ chmod +x file.sh

您可能会因为输入方式(带有管道,胡萝卜等)而收到错误b / c。您也可以尝试将条件分为两个:

if [ $# -lt 3 ] || [ $# -gt 3 ]; then
   echo "Error... Usage: $0 host database username"
   exit 0
fi

或者,由于您正在使用bash,因此可以使用内置语法:

if [[ $# -lt 3 || $# -gt 3 ]]; then
   echo "Error... Usage: $0 host database username"
   exit 0
fi

最后,您当然可以只检查是否给出了3个参数(干净,保持POSIX shell兼容性):

if [ $# -ne 3 ]; then
   echo "Error... Usage: $0 host database username"
   exit 0
fi

我仍然遇到相同的错误。我不确定代码在哪里出了错
markcruz 2011年

很奇怪,我剪切并粘贴了您的代码,它按预期工作。还有更多错误输出吗?很多时候bash会列出行号。另外,您正在运行什么系统?(Linux,MacOS,BSD,发行版等)
aaronstacy 2011年

1

正如我刚刚发现的那样,在函数定义上缺少右括号将导致此错误。

function whoIsAnIidiot() {
    echo "you are for forgetting the closing brace just below this line !"

当然应该是这样的...

function whoIsAnIidiot() {
    echo "not you for sure"
}

0

我只是将您的示例剪切并粘贴到文件中;它在bash下运行良好。我没有发现任何问题。

尽管bash无关紧要,但您可能需要确保以换行符结尾。(无论有没有最后的换行符,它都会为我运行。)

如果您不小心将控制字符嵌入文件中,则有时会看到奇怪的错误。由于这是一个简短的脚本,因此可以尝试通过将您的问题中的脚本粘贴到StackOverflow上,或者只是简单地重新键入来创建新脚本。

您正在使用什么版本的bash?(bash --version

祝好运!


0

确保存在.sh文件的目录名称没有空格字符。例如:说如果它位于一个名为“ New Folder”的文件夹中,那么您肯定会遇到所引用的错误。而是将其命名为“ New_Folder”。我希望这有帮助。


0

显然,当脚本的最后一行缺少换行符时,某些版本的Shell也会发出此消息。


0

在Ubuntu中:

$ gedit ~/.profile

然后,File -> Save as设置end lineUnix/Linux



0

对于使用MacOS的人:

如果收到Windows格式的文件,并且想在MacOS上运行并看到此错误,请运行以下命令。

brew install dos2unix
sh <file.sh>

0

就我而言,\以下是多余的:

function foo() {
    python tools/run_net.py \
                           --cfg configs/Kinetics/X3D_8x8_R50.yaml \
                           NUM_GPUS 1 \
                           TRAIN.BATCH_SIZE 8 \
                           SOLVER.BASE_LR 0.0125 \
                           DATA.PATH_TO_DATA_DIR ./afs/kinetics400 \
                           DATA.PATH_PREFIX  ./afs/kinetics400  \  # Error
}

不是一个\在结束DATA.PATH_PREFIX ./afs/kinetics400

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.