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

Mat*_*ady 2 command-line bash scripts windows-10 windows-subsystem-for-linux

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

#!/usr/bin/env bash
if [ 1 == 1 ]; then
echo "Something"
fi
Run Code Online (Sandbox Code Playgroud)

当我运行这个

sh ./test.sh
Run Code Online (Sandbox Code Playgroud)

我得到:

./test.sh: 4: ./test.sh: Syntax error: "fi" unexpected (expecting "then")
Run Code Online (Sandbox Code Playgroud)

它似乎无法识别我在那里的“然后”。关于为什么的任何线索?如果这部分很重要,这是适用于 Windows 的 Ubuntu。

运行 shell 脚本一般不是问题,它似乎只是在使用 if/else。

ter*_*don 6

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

chmod a+x ./test.sh
Run Code Online (Sandbox Code Playgroud)

然后运行它:

./test.sh
Run Code Online (Sandbox Code Playgroud)

或者,使用 bash 显式运行它:

bash ./test.sh
Run Code Online (Sandbox Code Playgroud)

这将使它运行bash而不是sh使用更有限的外壳并且不理解==. 这给我们带来了第二个问题以及为什么会失败。奇怪的是,您想要eqor =,而不是==。在 POSIX shell 脚本中测试数值相等性的操作符(sh是一个符合 POSIX 的 shell),-eq而测试字符串相等性的操作=并且==不是一回事。

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

if [ 1 = 1 ]; then
    echo "Something"
fi
Run Code Online (Sandbox Code Playgroud)

其中检查该字符串 1相同的字符串 1,或数字比较,使用:

if [ 1 -eq 1 ]; then
    echo "Something"
fi
Run Code Online (Sandbox Code Playgroud)

此外,您还有另一个问题。我只能重现你在得到具体的错误dash,如果我加入\r之后then。这是在 Windows 和 Linux 之间移动时的经典问题。当 Linux\n用作行结束符时,Windows 以\r\n. 该\r字符对用户不可见,但它存在并且会混淆脚本。因此,您可以使用以下方法将其删除:

sed -i 's/\r//' ./test.sh
Run Code Online (Sandbox Code Playgroud)

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