如果shell脚本中的/ Else在Ubuntu for Windows中引发错误

这是一个简单的shell脚本示例:

#!/usr/bin/env bash if [ 1 == 1 ]; then echo "Something" fi 

当我跑这个

 sh ./test.sh 

我明白了:

 ./test.sh: 4: ./test.sh: Syntax error: "fi" unexpected (expecting "then") 

它似乎没有认出我在那里的’那么’。 任何线索为什么? 这是部分重要的Ubuntu for Windows。

一般运行shell脚本不是问题,它似乎与if / else斗争。

这里有两个问题。 首先,当你有一个调用bash的shebang行时 ,你正在以sh script.shforms执行脚本。 shebang行已经为此脚本指定了解释器。 所以,只需使脚本可执行:

 chmod a+x ./test.sh 

然后运行它:

 ./test.sh 

或者,明确地使用bash运行它:

 bash ./test.sh 

这将使它与bash而不是sh运行,这是一个更有限的shell并且不理解== 。 这带来了第二个问题以及为什么会失败。 奇怪的是,你想要eq= ,而不是== 。 在POSIX shell脚本中测试数字相等性的运算符( sh是符合POSIX的shell)是-eq而测试字符串相等性的运算符是===不是一个东西。

因此,如果您希望脚本由sh运行,请将其更改为:

 if [ 1 = 1 ]; then echo "Something" fi 

检查字符串 1是否与字符串 1相同,或者以数字方式进行比较,使用:

 if [ 1 -eq 1 ]; then echo "Something" fi 

另外,你还有另外一个问题。 如果我在那then添加\r ,我只能重现你在dash获得的特定错误。 在Windows和Linux之间移动时,这是一个经典问题。 虽然Linux使用\n作为行结束字符,但Windows以\r\n结束其行。 这个\r字符对用户不可见,但它存在并且会混淆脚本。 所以,您可以删除它:

 sed -i 's/\r//' ./test.sh 

在将来,使用适当的文本编辑器编写脚本。 在WSL系统中工作的那个,或者至少可以配置为不将\r添加到其行的末尾的那个。

让我们保持简单:

  • sh不是Ubuntu上的bash (请参阅此参考)。

  • [是一个命令,与test命令相同。 它不支持==进行算术比较。 请改用-eq 。 这是POSIX标准指定的实用程序之一,因此可以在bashdash

     if [ 1 -eq 1 ]; then echo "it works!" fi 
  • bash((这叫做算术扩展。这支持== 。这个function显然是从ksh shell借来的。

     $ var=25 bash -c 'if((var==5)); then echo Y;else echo "N";fi' N $ var=25 bash -c 'if((var==25)); then echo Y;else echo "N";fi' Y 
  • 尽管dash不支持if (()) ,但是在任何一个shell $((因为它是由POSIX标准强制执行的。)只采用两个shell共有的function,我们可以做这样的事情,同时仍然使用==进行比较:

     $ var=25 dash -c 'if [ $((var==25)) -eq 1 ];then echo Y; else echo N;fi' Y $ var=25 dash -c 'if [ $((var==5)) -eq 1 ];then echo Y; else echo N;fi' N 

  • 我们可以完全抛弃if语句而不是用case (注意返回状态符合C,而不是shell行为,即true为1而false为0,而不是shell中的反过来):

     $ dash -c 'case $((1==1)) in 1) echo "equal";; 0) echo "not equal";;esac' equal $ dash -c 'case $((1==2)) in 1) echo "equal";; 0) echo "not equal";;esac' not equal 
  • 或者我们可以使用算术扩展偷偷摸摸(ab):

     $ var=25 dash -c '_0(){ false;}; _1(){ true;}; if "_$((var==25))" ; then echo Y; else echo N; fi'