【问题标题】:Bash syntax error: unexpected end of fileBash 语法错误:文件意外结束
【发布时间】:2011-09-16 00:41:51
【问题描述】:

请原谅我,这是一个非常简单的 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 后:

语法错误:文件意外结束

【问题讨论】:

    标签: bash syntax


    【解决方案1】:

    我认为 file.sh 带有 CRLF 行终止符。

    运行

    dos2unix file.sh
    

    那么问题就解决了。

    你可以在 ubuntu 中安装 dos2unix:

    sudo apt-get install dos2unix
    

    【讨论】:

    • 这个问题背后的原因是什么?我通常在 Windows 上工作,但需要将脚本传输到 unix 系统。
    • windows中的换行符是“\r\n”,而linux中的换行符是“\n”。
    • @KeesdeKooter 我不会仅仅因为某些东西对你不起作用就应该对它投反对票,显然它对 28 个投赞成票有效。一个简单的它对我不起作用就足够了。这就是为什么 SO 允许对一个问题有多个答案的原因,因为一个问题可以有多种解决方案。
    • Using notepad++ editor Edit>EOL Conversion>Old Mac Format 帮我解决了。
    • 在安装之前可以尝试(在 vim 中)':set fileformat=unix'。这在适用于 Linux 的 Windows 子系统 (WSL) 中对我有用。
    【解决方案2】:

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

    • 用分号结束单行函数体

    即这个看起来很无辜的 sn-p 会导致同样的错误:

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

    为了让愚蠢的解析器开心:

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

    【讨论】:

    • +1 也适用于带括号的代码 sn-ps,如下所示: [[ "$#" == 1 ]] && [[ "$arg" == [1,2,3,4 ] ]] && printf "%s\n" "废话" || { printf "%s\n" "blahblah";用法; } .......... 请注意波浪括号内的分号,就在调用一些先前定义的函数“用法”之后。忘记这会得到相同的语法错误:意外的 eof。
    • 你成功了。实际上,简单的事情是; 每个语句都应该以; 结尾,所以把它放在最后,例如:if [ -f ~/.git-completion.bash ]; then . ~/.git-completion.bash fi 会产生那个错误,而if [ -f ~/.git-completion.bash ]; then . ~/.git-completion.bash; fi; 不会......以冒号结尾,即:.bashfi 之后。
    • 我在一个 zsh 用户与我共享的脚本中得到了这个。前者在zsh 中有效,但在shbash 中无效。希望我是 4 个人,所以我可以给这 4 票
    【解决方案3】:

    我也刚刚通过在 if 子句中使用错误的语法得到了这个错误消息

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

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

    【讨论】:

    • 非常感谢......有人请给这家伙一枚奖章
    【解决方案4】:

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

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

    例如

    set -x
    trap read debug
    

    【讨论】:

    • 我完全忘记了“fi”!谢谢 :) 如果可以的话,为了大家的利益,请详细说明您使用陷阱的技巧。
    • 抱歉耽搁了,我的朋友。 ''trap' 命令是一种通过在每一行之后中断来调试脚本的方法。更全面的讨论在这里:stackoverflow.com/questions/9080431/…
    • 这很有用,非常感谢。请注意,unexpected end of file 错误将在fi 被击中时立即发生。
    【解决方案5】:

    我从this similar problem on StackOverflow得到这个答案

    在 Vim 中打开文件并尝试

    :set fileformat=unix

    将 eh 行结尾转换为 unix 结尾,看看是否解决了 问题。如果在 Vim 中编辑,输入命令 :set fileformat=unix 和 保存文件。其他几个编辑器具有转换行的能力 结尾,例如 Notepad++ 或 Atom

    谢谢@lemongrassnginger

    【讨论】:

    • 这些只是作为接受的答案建议的dos2unix 的替代方法。
    【解决方案6】:

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

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

    写多行解决了我的问题:

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

    【讨论】:

    • 您也可以将其保留为这样的一行:if [ -f ~/.git-completion.bash ]; then . ~/.git-completion.bash; fi(注意末尾附近的;)。
    【解决方案7】:

    在 cygwin 上我需要:-

     export SHELLOPTS
     set -o igncr
    

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

    【讨论】:

      【解决方案8】:

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

      cat > temp.txt < EOF
      some content
      EOF
      

      问题是我将上面的代码复制到了一个函数中,并无意中标记了代码。需要确保最后一个 EOF 没有选项卡。

      【讨论】:

      • 这正是我的情况。我将EOF 缩进了四个空格,因此 bash 没有解析它。删除空格解决了这个问题。
      【解决方案9】:

      这发生在我尝试使用括号调用函数时,例如

      run() {
        echo hello
      }
      
      run()
      

      应该是:

      run() {
        echo hello
      }
      
      run
      

      【讨论】:

        【解决方案10】:

        函数定义中缺少右大括号会导致我刚刚发现的这个错误。

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

        当然应该是这样的……

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

        【讨论】:

          【解决方案11】:

          对于 WINDOWS:

          就我而言,我在 Windows 操作系统上工作,但在运行 autoconf 时遇到了同样的错误。

          • 我只需使用我的 NOTEPAD++ IDE 打开 configure.ac 文件。
          • 然后我将EOL转换成Windows (CR LF)的文件如下:

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

          【讨论】:

            【解决方案12】:

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

            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 末尾有一个NOT\

            【讨论】:

              【解决方案13】:

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

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

              【讨论】:

              • 我仍然遇到同样的错误。我不确定代码哪里出错了
              • 奇怪,我剪切并粘贴了您的代码,它按预期工作。还有更多错误输出吗?很多时候 bash 会列出一个行号。另外,你运行的是什么系统? (Linux、MacOS、BSD、发行版等)
              【解决方案14】:

              我刚刚将您的示例剪切并粘贴到一个文件中;它在 bash 下运行良好。我认为它没有任何问题。

              为了更好的衡量,您可能希望确保它以换行符结尾,尽管 bash 不应该在意。 (不管有没有最后的换行符,它都对我有用。)

              如果您不小心在文件中嵌入了控制字符,您有时会看到奇怪的错误。由于它是一个简短的脚本,请尝试通过在 StackOverflow 上粘贴您的问题中的新脚本来创建一个新脚本,或者只需重新输入它。

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

              祝你好运!

              【讨论】:

                【解决方案15】:

                确保 .sh 文件所在目录的名称没有空格字符。例如:假设它位于名为“新文件夹”的文件夹中,您一定会遇到您引用的错误。相反,只需将其命名为“New_Folder”。我希望这会有所帮助。

                【讨论】:

                  【解决方案16】:

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

                  【讨论】:

                    【解决方案17】:

                    在 Ubuntu 中:

                    $ gedit ~/.profile
                    

                    然后,File -&gt; Save as 并将 end line 设置为 Unix/Linux

                    【讨论】:

                      【解决方案18】:

                      我知道我来晚了。希望这可以帮助某人。

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

                      在这里讨论:Unable to source a simple bash script

                      【讨论】:

                        【解决方案19】:

                        对于使用 MacOS 的人:

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

                        brew install dos2unix
                        sh <file.sh>
                        

                        【讨论】:

                          【解决方案20】:

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

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

                          两者都可以使用vimvi 修复。

                          要修复行尾,请在 vim 中打开文件并从命令模式键入:

                          :set ff=unix
                          

                          要删除 BOM,请使用:

                          :set nobomb
                          

                          【讨论】:

                            【解决方案21】:

                            对于那些没有安装 dos2unix 的人(并且不想安装它):

                            删除导致此错误的尾随 \r 字符:

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

                            来自这个 StackOverflow 答案的详细信息。这真的很有帮助。 https://stackoverflow.com/a/32912867/7286223

                            【讨论】:

                              猜你喜欢
                              • 1970-01-01
                              • 1970-01-01
                              • 1970-01-01
                              • 2012-03-22
                              • 2013-06-08
                              • 1970-01-01
                              • 2017-06-08
                              • 2013-04-13
                              相关资源
                              最近更新 更多