如何在传递ShellCheck时通过环境变量将glob传递给shell脚本

Dom*_*nic 6 bash shell shellcheck

假设我有一个shell脚本,test.sh它应该回显一些值.我希望能够通过具有glob扩展的环境变量传递这些值:

$ ls
1.js  2.js  test.sh*

$ FOO="*.js" bash ./test.sh
1.js 2.js
Run Code Online (Sandbox Code Playgroud)

你说容易!写吧

#!/bin/bash
echo $FOO
Run Code Online (Sandbox Code Playgroud)

事实上,这是有效的.但它没有通过ShellCheck,后者通过使用隐式globbing /扩展(SC2086)来调用我们.(这是公平的;在原始代码中,回声线是cp $FOO $BAR,确实我们不想扩展$BAR;这个错误捕获了错误.)

所以,为了使这个更明确,我希望以下可能会起作用:

#!/bin/bash
array=( $FOO )
echo "${array[@]}"
Run Code Online (Sandbox Code Playgroud)

但不是:我们最终得到了SC2206.

是否有规范的方式来做这种事情,这属于ShellCheck作者认为的最佳实践?(请随意使用www.shellcheck.net上的在线检查程序对其进行测试.)这完全是错误的做法吗?ShellCheck的作者似乎不太可能想到这个用例......

Leo*_*eon 6

在这种情况下,ShellCheck的警告似乎没有安全的解决方法.但是,ShellCheck的诊断并不是普遍的事实.您可能已经注意到,其某些警告的文档包括" 例外"部分.对于SC2206,它读取:

例外:

如果您已经注意(通过设置IFSset -f)按照您的意图进行单词分割,则可以忽略此警告.

现在,ShellCheck提供了根据具体情况忽略警告的指令:

Shellcheck指令允许您有选择地忽略警告,并采用文件中的注释形式:

hexToAscii() {
  # shellcheck disable=SC2059
  printf "\x$1"
}
Run Code Online (Sandbox Code Playgroud)

支持的指令是

shebang代替或紧接在整个脚本之后的指令.否则,它们的范围限定在它后面的结构(例如case语句的所有分支或整个函数).

因此,您可以按如下方式禁止警告:

#!/usr/bin/env bash

# The following line is needed so that the shellcheck directive
# below doesn't have global effect
:

# shellcheck disable=SC2206
array=( $FOO )
echo "${array[@]}"
Run Code Online (Sandbox Code Playgroud)