无法弄清楚如何解决 shellcheck 投诉,即在从另一个脚本启动一个脚本时我不应该使用 glob 作为命令

Posted

技术标签:

【中文标题】无法弄清楚如何解决 shellcheck 投诉,即在从另一个脚本启动一个脚本时我不应该使用 glob 作为命令【英文标题】:Cannot figure out how to fix shellcheck complaint that I should not use a glob as a command when starting one script from another 【发布时间】:2018-08-07 10:24:56 【问题描述】:

示例脚本:

#!/bin/bash

printf '1\n1\n1\n1\n' | ./script2*.sh >/dev/null 2>/dev/null

Shellcheck 返回以下内容:

In script1.sh line 3:
printf '1\n1\n1\n1\n' | ./script2*.sh >/dev/null 2>/dev/null
                        ^-- SC2211: This is a glob used as a command name. Was it supposed to be in $.., array, or is it missing quoting?

根据https://github.com/koalaman/shellcheck/wiki/SC2211,这条规则应该没有例外。

具体来说,它建议“如果您想通过 glob 指定命令名称,例如在 ./myprogram-*/foo 中不硬编码版本,请先扩展为数组或参数以允许处理 0 或 2+ 的情况匹配。”

我首先使用 glob 的原因是我将日期附加或更改到我刚刚创建或更改的任何脚本。有趣的是,当我使用“bash script2*.sh”而不是“./script2*.sh”时,抱怨就消失了。

我是否解决了这个问题,或者我在欺骗 shellcheck 忽略一个不应被忽略的问题?如果我使用了错误的 bash 语法,我该如何执行另一个需要引用以使用 glob 正确方式的脚本?

【问题讨论】:

【参考方案1】:

问题在于./script2*.sh 可能最终会运行

./script2-20171225.sh ./script2-20180226.sh ./script2-copy.sh

这是一件奇怪且可能是无意的事情,尤其是当脚本被此类参数混淆时,或者如果您希望使用最新的文件。您的“修复”具有相同的基本问题。

您提到的建议将采取以下形式:

array=(./script2*.sh)
[ "$#array[@]" -ne 1 ] &&  echo "Multiple matches" >&2; exit 1; 
"$array[0]"

并提防这个问题。

由于您似乎假设您只会有一个匹配的文件在没有参数的情况下被调用,您可以将其变成一个函数:

runByGlob() 
  if (( $# != 1 ))
  then
    echo "Expected exactly 1 match but found $#: $*" >&2
    exit 1
  elif command -v "$1" > /dev/null 2>&1
  then
    "$1"
  else
    echo "Glob is not a valid command: $*" >&2
    exit 1
  fi


whatever | runByGlob ./script2*.sh

现在,如果您有零个或多个匹配的文件,它将因错误而中止,而不是可能运行带有奇怪参数的错误文件。

【讨论】:

以上是关于无法弄清楚如何解决 shellcheck 投诉,即在从另一个脚本启动一个脚本时我不应该使用 glob 作为命令的主要内容,如果未能解决你的问题,请参考以下文章

无法弄清楚如何修复错误

无法弄清楚如何解决在二叉树中返回两个总和为目标值的值的逻辑缺陷

无法弄清楚有效载荷是如何工作的

无法弄清楚这种重复的复杂性

如何在 HexaPDF 中使用多种字体,即复合字体

C++:无法弄清楚如何正确隐藏实现细节