无法弄清楚如何修复 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

示例脚本:

#!/bin/bash

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

Shellcheck returns 以下内容:

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,这条规则应该没有例外。

具体来说,建议"If you want to specify a command name via glob, e.g. to not hard code version in ./myprogram-*/foo, expand to array or parameters first to allow handling the cases of 0 or 2+ matches."

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

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

问题是 ./script2*.sh 可能会变成 运行

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

这是一件奇怪且可能是无意的事情,特别是如果脚本被此类参数混淆,或者如果您希望使用最 up-to-date 文件。你的 "fix" 有同样的根本问题。

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

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 "" > /dev/null 2>&1
  then
    ""
  else
    echo "Glob is not a valid command: $*" >&2
    exit 1
  fi
}

whatever | runByGlob ./script2*.sh

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