意外标记“完成”附近的 BASH 语法错误

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18367708/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 00:05:17  来源:igfitidea点击:

BASH Syntax error near unexpected token 'done'

bash

提问by user1837725

Any idea of what the problem could be?

知道问题可能是什么吗?

My code is:

我的代码是:

#!/bin/bash
while :
do
echo "Press [CTRL+C] to stop.."
sleep 1
done

Saved it as .sh and ran bash file.sh

将它保存为 .sh 并运行 bash file.sh

CentOS 6 32-bit

CentOS 6 32 位

What is the issue? First time EVER using BASH, need it for a simple infinite loop on something.

问题是什么?第一次使用 BASH,需要它来进行简单的无限循环。

回答by that other guy

Run cat -v file.sh.

运行cat -v file.sh

You most likely have a carriage return or no-break space in your file. cat -vwill show them as ^Mand M-BM-or M-respectively. It will similarly show any other strange characters you might have gotten into your file.

您的文件中很可能有回车或不间断空格。cat -v将它们分别显示为^MM-BM-M-。它同样会显示您可能已经进入文件的任何其他奇怪字符。

Remove the Windows line breaks with

删除 Windows 换行符

tr -d '\r' < file.sh > fixedfile.sh

回答by Kunal B.

I was getting the same error on Cygwin; I did the following (one of them fixed it):

我在 Cygwin 上遇到了同样的错误;我做了以下事情(其中一个修复了它):

  1. Converted TABSto SPACES
  2. ran dos2unixon the .(ba)shfile
  1. 转换TABSSPACES
  2. RANdos2unix.(ba)sh文件

回答by David W.

What is the error you're getting?

你得到的错误是什么?

$ bash file.sh
test.sh: line 8: syntax error: unexpected end of file

If you get that error, you may have bad line endings. Unix uses <LF>at the end of the file while Windows uses <CR><LF>. That <CR>character gets interpreted as a character.

如果出现该错误,则可能是行尾错误。Unix 使用<LF>文件末尾,而 Windows 使用<CR><LF>. 该<CR>字符被解释为一个字符。

You can use od -a test.shto see the invisiblecharacters in the file.

您可以使用od -a test.sh来查看文件中的不可见字符。

$ od -a test.sh
0000000    #   !   /   b   i   n   /   b   a   s   h  cr  nl   #  sp  cr
0000020   nl   w   h   i   l   e  sp   :  cr  nl   d   o  cr  nl  sp  sp
0000040   sp  sp   e   c   h   o  sp   "   P   r   e   s   s  sp   [   C
0000060    T   R   L   +   C   ]  sp   t   o  sp   s   t   o   p   "  cr
0000100   nl  sp  sp  sp  sp   s   l   e   e   p  sp   1  cr  nl   d   o
0000120    n   e  cr  nl                                                
0000124

The spstands for space, the htstands for tab, the crstands for <CR>and the nlstands for <LF>. Note that all of the lines end with crfollowed by a nlcharacter.

sp代表的空间,ht代表选项卡上,cr代表<CR>nl代表<LF>。请注意,所有行都以后cr跟一个nl字符结尾。

You can also use cat -v test.shif your catcommand takes the -vparameter.

cat -v test.sh如果您的cat命令采用-v参数,您也可以使用。

If you have dos2unixon your box, you can use that command to fix your file:

如果您dos2unix的盒子上有,您可以使用该命令来修复您的文件:

$ dos2unix test.sh

回答by Mihit Gandhi

Sometimes this error happens because of unexpected CR characters in file, usually because the file was generated on a Windows system which uses CR line endings. You can fix this by running os2unixor tr, for example:

有时发生此错误是因为文件中出现意外的 CR 字符,通常是因为该文件是在使用 CR 行结尾的 Windows 系统上生成的。您可以通过运行os2unix或来解决此问题tr,例如:

tr -d '\015' < yourscript.sh > newscript.sh

tr -d '\015' < yourscript.sh > newscript.sh

This removes any CR characters from the file.

这将从文件中删除任何 CR 字符。

回答by justbrowsing

Open new file namedfoobar

打开名为的新文件foobar

nano -w foobar

Input script

输入脚本

 #!/bin/bash
 while [ 0 = 0 ]; do
   echo "Press [CTRL+C] to stop.."
   sleep 1
 done;

Exit and save

退出并保存

CTRL+Xthen Yand Enter

CTRL+X然后YEnter

Set script executable and run

设置脚本可执行并运行

chmod +x foobar
./foobar

回答by sauna-l

Might help someone else : I encountered the same kind of issues while I had done some "copy-paste" from a side Microsoft Word document, where I took notes, to my shell script(s).

可能会帮助其他人:当我从 Microsoft Word 文档(我在其中做笔记)“复制粘贴”到我的 shell 脚本时,我遇到了同样的问题。

Re-writing, manually, the exact same code in the script just solved this.

手动重写脚本中完全相同的代码刚刚解决了这个问题。

It was quite un-understandable at first, I think Word's hidden characters and/or formatting were the issue. Obvious but not see-able ... I lost about one hour on this (I'm no shell expert, as you might guess ...)

一开始是很难理解的,我认为 Word 的隐藏字符和/或格式是问题所在。明显但不可见......我在这个上浪费了大约一个小时(我不是shell专家,你可能会猜到......)

回答by charliegreen

There's a way you can get this problem without having mixed newline problems (at least, in my shell, which is GNU bash v4.3.30):

有一种方法可以解决这个问题而不会出现混合换行问题(至少,在我的 shell 中,它是 GNU bash v4.3.30):

#!/bin/bash
# foo.sh

function foo() {
    echo "I am quoting a thing `' inside a function."
}

while [ "$input" != "y" ]; do
    read -p "Hit `y' to continue: " -n 1 input
    echo
done

foo "What could possibly go wrong?"
$ ./foo.sh
./foo.sh: line 11: syntax error near unexpected token `done'
./foo.sh: line 11: `done'

This is because bash expands backticks inside double-quoted strings (see the bash manual on quotingand command substitution), and before finding a matching backtick, will interpret any additional double quotes as part of the command substitution:

这是因为 bash 在双引号字符串中扩展反引号(请参阅有关引用命令替换的 bash 手册),并且在找到匹配的反引号之前,会将任何额外的双引号解释为命令替换的一部分:

$ echo "Command substitution happens inside double-quoted strings: `ls`"
Command substitution happens inside double-quoted strings: foo.sh
$ echo "..even with double quotes: `grep -E "^foo|wrong" foo.sh`"
..even with double quotes: foo "What could possibly go wrong?"

You can get around this by escaping the backticks in your string with a backslash, or by using a single-quoted string.

您可以通过使用反斜杠转义字符串中的反引号或使用单引号字符串来解决此问题。

I'm not really sure why this only gives the one error message, but I think it has to do with the function definition:

我不确定为什么这只会给出一个错误消息,但我认为这与函数定义有关:

#!/bin/bash
# a.sh

function a() {
    echo "Thing's `quoted'"
}
a
while true; do
    echo "Other `quote'"
done
#!/bin/bash
# b.sh

echo "Thing's `quoted'"
while true; do
    echo "Other `quote'"
done
$ ./a.sh
./a.sh: line 10: syntax error near unexpected token `done'
./a.sh: line 10: `done'
$ ./b.sh
./b.sh: command substitution: line 6: unexpected EOF while looking for matching `''
./b.sh: command substitution: line 9: syntax error: unexpected end of file
Thing's quote'
./b.sh: line 7: syntax error near unexpected token `done'
./b.sh: line 7: `done'

回答by Yohei

I had same problem, but solved.

我有同样的问题,但解决了。

I removed the following line in .bashrc

我在 .bashrc 中删除了以下行

alias do="docker.exe" # this line caused the problem

I use WSL(windows subsystem for linux)

我使用 WSL(Linux 的 Windows 子系统)

回答by lampShadesDrifter

Had similar problems just now and these are two separate instances and solutions that worked for me:

刚才遇到了类似的问题,这些是对我有用的两个单独的实例和解决方案:

Case 1.Basically, had a space after the last commandwithin my newline-separatedfor-loop, eg. (imagining that |here represents the carat in a text editor showing where you are writing), this is what I saw when clicking around the end of the line of the last command in the loop:

案例 1.基本上,在我的换行符分隔的for 循环中的最后一个命令之后有一个空格,例如。(想象一下,这里代表文本编辑器中的克拉,显示您正在写的位置),这是我在循环中单击最后一个命令的行尾时看到的:|

for f in $pathToFiles
do
   $stuff |
done

Notice the space before before the carat (so far as I know, this is something cathas no option do display visually (one way you couldtest is with something like od -bc yourscript.sh)). Changing the code to

请注意克拉之前的空间(据我所知,这是cat无法在视觉上显示的选项(您可以测试的一种方法是使用od -bc yourscript.sh))。将代码更改为

for f in $pathToFiles
do
   $stuff| <--- notice the carat shows no ending space before the newline
done

fixed the problem.

解决了这个问题。

Case 2.Was using a pseudo try-catch block for the for-loop (see https://stackoverflow.com/a/22010339/8236733) like

案例 2.为 for 循环使用伪 try-catch 块(参见https://stackoverflow.com/a/22010339/8236733),例如

{
for f in $pathToFiles
do
   { $stuff } || { echo "Failed to complete stuff"; exit 255; }
done
} || { echo "Failed to complete loop"; exit 255; }

and apparently bash did not like the nested {}s. Changing to

显然 bash 不喜欢嵌套的{}s。更改为

{
for f in $pathToFiles
do
   $stuff
done
} || { echo "Failed to complete loop"; exit 255; }

fixed the problem in this case. If anyone can further explain either of these cases, please let me know more about them in the comments.

解决了这种情况下的问题。如果有人可以进一步解释这两种情况,请在评论中让我了解更多。

回答by santy

Edit your code in any linux environment then you won't face this problem. If edit in windows notepad any space take it as ^M.

在任何 linux 环境中编辑你的代码,你就不会遇到这个问题。如果在 Windows 记事本中编辑任何空间都将其作为 ^M。