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

请原谅我在 Bash 中使用了一个非常简单的脚本,代码如下:

#!/bin/bash
# june 2011


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

在运行 sh 文件后:

语法错误: 文件意外结束

342184 次浏览

我能够剪切和粘贴你的代码到一个文件,它运行正确。如果你 像这样执行它应该可以工作:

你的“ 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

您可能会得到关于如何进行输入的错误提示(w/a 管道,胡萝卜, 你也可以尝试把条件分成两部分:

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个参数(clean, 维护 POSIX shell 兼容性) :

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

我只是将您的示例剪切粘贴到一个文件中; 它在 bash 下运行良好。我看不出有什么问题。

为了方便起见,您可能需要确保它以换行结束,但 bash 不应该关心这个问题。(不管有没有最后一行换行符,它都适用于我。)

如果不小心在文件中嵌入了控制字符,您有时会看到奇怪的错误。因为它是一个简短的脚本,所以可以尝试创建一个新的脚本,方法是将问题粘贴到 StackOverflow 上,或者只是重新键入它。

您使用哪个版本的 bash? (bash --version)

祝你好运!

我认为 file.sh 使用了 CRLF 行终止符。

快跑

dos2unix file.sh

那问题就解决了。

你可以用这个在 ubuntu 中安装 dos2unix:

sudo apt-get install dos2unix

关于 Cygwin 我需要:-

 export SHELLOPTS
set -o igncr

这样我就不需要运行 unix2dos 了

另一件需要检查的事情(我刚刚想到) :

  • 带分号的单行函数的终止体

也就是说,这个看似无辜的片段将导致同样的错误:

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

为了让哑巴解析器高兴:

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

我也是因为在 if子句中使用了错误的语法才得到这个错误消息的

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

我通过注释比特来调试它,直到它正常工作

控件所在的目录的名称。Sh 文件没有空格字符。比如说,如果它在一个名为“新文件夹”的文件夹中,你一定会遇到你引用的错误。只需将其命名为“ New _ Folder”即可。希望这个能帮上忙。

所以我发现这个帖子,答案没有帮助我,但我能够找出为什么它给我的错误。我有一个

cat > temp.txt < EOF
some content
EOF

问题是我复制了上面的代码放在一个函数中,并且无意中标记了代码。需要确保最后一个 EOF 没有标签。

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

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

提示: 如果您的脚本很大,可以使用 Trap 进行调试..。

例如:。

set -x
trap read debug

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

在 Vim 中打开文件并尝试

:set fileformat=unix

将 Eh 行结尾转换为 unix 结尾,看看这是否解决了 如果在 Vim 中编辑,输入命令: set fileformat = unix 和 保存文件。其他几个编辑器有能力转换行 结尾,如记事本 + + 或原子

谢谢@柠檬草姜

在 Ubuntu 中:

$ gedit ~/.profile

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

当我在一行中写下“ if-fi”语句时,我遇到了这个问题:

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

写多行代码解决了我的问题:

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

我知道我来晚了,希望这能帮到别人。

检查你的.bashrc 文件。也许重命名或移动它。

此处讨论: 无法找到简单 bash 脚本的源代码

当我尝试使用括号调用函数时,就会发生这种情况,例如。

run() {
echo hello
}


run()

应该是:

run() {
echo hello
}


run

窗户:

在我的例子中,我正在使用 Windows 操作系统,在运行 autoconf 时也出现了同样的错误。

  • 我只需用我的 笔记本 + + IDE 打开 configure.ac 文件。
  • 然后,我将文件与 EOL转换为 视窗(CR LF)如下:

    编辑-> EOL 转换-> 视窗(CR LF)

对于使用 MacOS 的用户:

如果您接收到一个 Windows 格式的文件,并希望在 MacOS 上运行并看到此错误,请运行以下命令。

brew install dos2unix
sh <file.sh>

正如我刚刚发现的,在函数定义中缺少一个结束大括号将导致此错误。

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

当然应该是这样..。

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

在我的例子中,有一个冗余的 \,如下所示:

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的末尾有 没有 a \

如果 脚本本身是有效的,并且没有语法错误,那么一些可能的原因可能是:

  • 无效的行尾(例如,\r\n而不是 \n)
  • 在文件的开头出现 byte order mark(BOM)

两者都可以使用 vimvi固定。

若要修复行结束符,请在 vim 中从命令模式类型打开文件:

:set ff=unix

删除 BOM 的使用:

:set nobomb

对于那些没有安装 Dos2unix(也不想安装它)的人:

删除导致此错误的后跟 \r字符:

sed -i 's/\r$//' filename

这个 StackOverflow 回答的细节,真的很有帮助。 Https://stackoverflow.com/a/32912867/7286223