如何在传递 ShellCheck 时通过环境变量将 glob 传递给 shell 脚本
Posted
技术标签:
【中文标题】如何在传递 ShellCheck 时通过环境变量将 glob 传递给 shell 脚本【英文标题】:How to pass a glob to a shell script via an environment variable while passing ShellCheck 【发布时间】:2018-02-06 11:08:48 【问题描述】:假设我有一个shell 脚本test.sh
,它应该回显一些值。我希望能够通过具有全局扩展的环境变量传递这些值:
$ ls
1.js 2.js test.sh*
$ FOO="*.js" bash ./test.sh
1.js 2.js
简单,你说!随便写
#!/bin/bash
echo $FOO
确实,这行得通。但它没有通过ShellCheck,这要求我们使用隐式通配符/扩展(SC2086)。 (这是公平的;在原始代码中,echo 行是cp $FOO $BAR
,实际上我们不想扩展$BAR
;这个错误会捕获错误。)
因此,为了使这一点更明确,我希望以下内容可能会起作用:
#!/bin/bash
array=( $FOO )
echo "$array[@]"
但不是:我们最终得到SC2206。
是否有一种规范的方式来做这种事情,这属于 ShellCheck 作者认为的最佳实践? (请随意使用 www.shellcheck.net 上的在线检查器进行测试。)这完全是错误的方法吗? ShellCheck 作者似乎不太可能从未想过这个用例......
【问题讨论】:
在 Twitter 上有人提到printf %q
和 xargs
: twitter.com/stuartpb/status/902411014724976641 。也许有人知道这些会有什么用。
【参考方案1】:
在这种情况下,ShellCheck 的警告似乎没有安全的解决方法。然而,ShellCheck 的诊断并不是普遍的真理。您可能已经注意到,其中一些警告的文档包含一个 Exceptions 部分。对于SC2206,其内容为:
例外情况:
如果您已经小心(通过设置
IFS
和set -f
) 按照您的意图进行分词工作,您可以忽略这一点 警告。
现在,ShellCheck 提供 directives 以逐个忽略警告:
Shellcheck 指令允许您选择性地忽略警告,并且 在文件中采用 cmets 的形式:
hexToAscii() # shellcheck disable=SC2059 printf "\x$1"
支持的指令是
disable
禁用警告:# shellcheck disable=code[,code...] statement_where_warning_should_be_disabled
...
指令代替 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[@]"
【讨论】:
以上是关于如何在传递 ShellCheck 时通过环境变量将 glob 传递给 shell 脚本的主要内容,如果未能解决你的问题,请参考以下文章