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

时间:2022-06-01 21:05:50

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文件。

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时,需要它在某个东西上进行简单的无限循环。

9 个解决方案

#1


18  

Run cat -v file.sh.

猫- v file.sh运行。

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

你很可能在你的文件中有一个回车或没有休息的空间。猫- v将展示他们^ M和M-BM或M -分别。它同样会显示你在文件中可能遇到的任何其他奇怪的字符。

Remove the Windows line breaks with

删除Windows换行符。

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

#2


8  

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

我在Cygwin上犯了同样的错误;我做了如下(其中一个修正了):

  1. Converted TABS to SPACES
  2. 将制表符转换为空格
  3. ran dos2unix on the .(ba)sh file
  4. 在.(ba)sh文件上运行dos2unix。

#3


3  

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在文件末尾使用 ,而Windows使用 。这个 字符被解释为一个字符。

You can use od -a test.sh to see the invisible characters in the file.

你可以用od -a测试。要查看文件中的不可见字符。

$ 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 sp stands for space, the ht stands for tab, the cr stands for <CR> and the nl stands for <LF>. Note that all of the lines end with cr followed by a nl character.

sp代表空间,ht代表tab, cr代表< cr >, nl代表 。注意,所有的行以cr结尾,后跟一个nl字符。

You can also use cat -v test.sh if your cat command takes the -v parameter.

你也可以使用cat -v测试。如果你的cat命令接受-v参数。

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

如果您的邮箱中有dos2unix,您可以使用该命令来修复您的文件:

$ dos2unix test.sh

#4


1  

Open new file named foobar

打开名为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+X then Y and Enter

按CTRL+X然后输入Y。

Set script executable and run

设置脚本可执行并运行。

chmod +x foobar
./foobar

#5


1  

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 ...)

这在一开始是很不容易理解的,我认为单词的隐藏字符和/或格式是问题。很明显,但不能看出来……我在这件事上损失了一个小时(我不是shell专家,你可能猜到了…)

#6


1  

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 os2unix or tr, for example:

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

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

tr -d '\015' <你的脚本。sh> newscript.sh

This removes any CR characters from the file.

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

#7


0  

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。

#8


0  

I have exactly the same issue as above, and took me the whole day to discover that it doesn't like my newline approach. Instead I reused the same code with semi-colon approach instead. For example my initial code using the newline (which threw the same error as yours):

我的问题和上面的完全一样,我花了一整天的时间才发现它不喜欢我的换行方法。相反,我用半冒号方法重用了相同的代码。例如,我使用newline的初始代码(与您的错误相同):

Y=1
while test "$Y" -le "20"
do
        echo "Number $Y"
        Y=$[Y+1]
done

And using code with semicolon approach with worked wonder:

用分号方法使用代码:

Y=1 ; while test "$Y" -le "20"; do echo "Number $Y"; Y=$[Y+1] ; done

I notice the same problem occurs for other commands as well using the newline approach, so I think I am gonna stick to using semicolon for my future code.

我注意到在其他命令中也出现了同样的问题,也使用了换行方法,因此我认为我将坚持使用分号作为将来的代码。

#9


0  

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 `$1' 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 quoting and command substitution), and before finding a matching backtick, will interpret any additional double quotes as part of the command substitution:

这是因为bash扩展了双引号内的backtick(参见bash手册中的引用和命令替换),在找到匹配的backtick之前,将解释任何额外的双引号作为命令替换的一部分:

$ 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'

#1


18  

Run cat -v file.sh.

猫- v file.sh运行。

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

你很可能在你的文件中有一个回车或没有休息的空间。猫- v将展示他们^ M和M-BM或M -分别。它同样会显示你在文件中可能遇到的任何其他奇怪的字符。

Remove the Windows line breaks with

删除Windows换行符。

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

#2


8  

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

我在Cygwin上犯了同样的错误;我做了如下(其中一个修正了):

  1. Converted TABS to SPACES
  2. 将制表符转换为空格
  3. ran dos2unix on the .(ba)sh file
  4. 在.(ba)sh文件上运行dos2unix。

#3


3  

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在文件末尾使用 ,而Windows使用 。这个 字符被解释为一个字符。

You can use od -a test.sh to see the invisible characters in the file.

你可以用od -a测试。要查看文件中的不可见字符。

$ 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 sp stands for space, the ht stands for tab, the cr stands for <CR> and the nl stands for <LF>. Note that all of the lines end with cr followed by a nl character.

sp代表空间,ht代表tab, cr代表< cr >, nl代表 。注意,所有的行以cr结尾,后跟一个nl字符。

You can also use cat -v test.sh if your cat command takes the -v parameter.

你也可以使用cat -v测试。如果你的cat命令接受-v参数。

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

如果您的邮箱中有dos2unix,您可以使用该命令来修复您的文件:

$ dos2unix test.sh

#4


1  

Open new file named foobar

打开名为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+X then Y and Enter

按CTRL+X然后输入Y。

Set script executable and run

设置脚本可执行并运行。

chmod +x foobar
./foobar

#5


1  

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 ...)

这在一开始是很不容易理解的,我认为单词的隐藏字符和/或格式是问题。很明显,但不能看出来……我在这件事上损失了一个小时(我不是shell专家,你可能猜到了…)

#6


1  

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 os2unix or tr, for example:

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

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

tr -d '\015' <你的脚本。sh> newscript.sh

This removes any CR characters from the file.

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

#7


0  

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。

#8


0  

I have exactly the same issue as above, and took me the whole day to discover that it doesn't like my newline approach. Instead I reused the same code with semi-colon approach instead. For example my initial code using the newline (which threw the same error as yours):

我的问题和上面的完全一样,我花了一整天的时间才发现它不喜欢我的换行方法。相反,我用半冒号方法重用了相同的代码。例如,我使用newline的初始代码(与您的错误相同):

Y=1
while test "$Y" -le "20"
do
        echo "Number $Y"
        Y=$[Y+1]
done

And using code with semicolon approach with worked wonder:

用分号方法使用代码:

Y=1 ; while test "$Y" -le "20"; do echo "Number $Y"; Y=$[Y+1] ; done

I notice the same problem occurs for other commands as well using the newline approach, so I think I am gonna stick to using semicolon for my future code.

我注意到在其他命令中也出现了同样的问题,也使用了换行方法,因此我认为我将坚持使用分号作为将来的代码。

#9


0  

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 `$1' 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 quoting and command substitution), and before finding a matching backtick, will interpret any additional double quotes as part of the command substitution:

这是因为bash扩展了双引号内的backtick(参见bash手册中的引用和命令替换),在找到匹配的backtick之前,将解释任何额外的双引号作为命令替换的一部分:

$ 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'