不要使用 if 和 for 获取 shell 脚本的输出

不要使用 if 和 for 获取 shell 脚本的输出

我没有得到任何打印结果,但我不明白为什么?

read -e -i "no" -p "Install? " result

if [ '$result' == 'yes' ]; then
  declare -a subs=('one' 'two')
  for sub in "${subs[@]}"
  do
    echo "$sub"
  done
fi

答案1

您需要使用双引号$result而不是单引号,否则它不会扩展。

[ '$result' == 'yes' ]永远不会评估为 true 因为它试图将文字$result与文字进行比较yes

此外,正如库萨拉南达指出的那样;运算==符用于 bash 测试构造,[[=运算符用于标准 (POSIX) 测试构造[

因此,您应该将该行更改为:[ "$result" = 'yes' ]


另一个值得了解的好工具是set内置命令及其-x开关,它们可用于跟踪您的脚本。如果您将其添加set -x到原始脚本的顶部并运行它,您将看到打印出以下内容:

+ read -e -i no -p 'Install? ' result
Install? yes
+ '[' '$result' == yes ']'

正如您所看到的,它试图将“$result”与“yes”进行比较。当正确引用时,您不会看到该变量$result,而是看到它的扩展,如下所示:

+ read -e -i no -p 'Install? ' result
Install? yes
+ '[' yes == yes ']'
+ subs=('one' 'two')
+ declare -a subs
+ for sub in '"${subs[@]}"'
+ echo one
one
+ for sub in '"${subs[@]}"'
+ echo two
two

每当您用脚本将头撞在墙上时,您应该打开set -x并跟踪它正在做什么以及哪里出了问题。

答案2

遵循@Jesse_b 的回答。

为什么需要双引号变量?

单引号和双引号的区别:

将字符括在单引号中可保留引号内每个字符的字面值。单引号之间不能出现单引号,即使前面有反斜杠也是如此。

将字符括在双引号中会保留引号内所有字符的字面值,但 $、`、\ 以及启用历史扩展时的 ! 除外。

man bash

这个你要记住,这样可以省去你一段时间调试的麻烦。

相关内容