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

use*_*695 6 shell bash

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

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
Run Code Online (Sandbox Code Playgroud)

jes*_*e_b 14

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

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

此外,正如 Kusalananda 指出的那样;该==操作员是对于bash测试构建体[[,而=操作者是用于标准(POSIX)测试的构建体[。

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


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

+ read -e -i no -p 'Install? ' result
Install? yes
+ '[' '$result' == yes ']'
Run Code Online (Sandbox Code Playgroud)

如您所见,它试图将“$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
Run Code Online (Sandbox Code Playgroud)

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

  • 此外,`[ ... ]` 中的 `=`,`[[ ... ]]` 中的 `==`。`[[ ... ]]` 是 `bash` 扩展语法。`[ ... ]` 是标准的 `test` 语法(使用 `=` 进行字符串比较)。 (4认同)
  • @Kusalananda,无论如何,`-p`、`-e`、`-i`、`declare` 都是bashisms。`[[ ... ]]` 来自 `ksh`。所有支持 `[[...]]`(包括 `bash`)的 shell 也支持 `==` 作为其内置 `[` 命令中 `=` 的替代。不过,我仍然坚持使用 `=` 而不是 `==`。`[[...]]` 或 `[` 中没有赋值,因此无需消除 == 与 = 的歧义。 (4认同)