1

最初发布这个问题时,我完全用错了,获得了另一个合理但不同的问题,在这里得到了正确的回答。

以下是我最初想问的问题的正确版本。

在我的一个 Bash 脚本中,有一点我有一个变量SCRIPT,其中包含/path/to/an/exe在执行时输出一个line to be executed.

我的脚本最终需要做的是执行line to be executed. 因此脚本的最后一行是

$($SCRIPT)

所以$SCRIPT扩展为/path/to/an/exe, 并$(/path/to/an/exe)执行可执行文件并返回line to be executed, 然后执行。

但是,shellcheck在脚本上运行会生成此错误:

In setscreens.sh line 7:
$($SCRIPT)
^--------^ SC2091: Remove surrounding $() to avoid executing output.

For more information:
  https://www.shellcheck.net/wiki/SC2091 -- Remove surrounding $() to avoid e...

$($SCRIPT)有没有办法以更合适的方式重写它?eval在这里似乎没有太大帮助。

4

4 回答 4

3

您可以通过将要执行的命令设置为 shell 中的位置参数并从命令行执行它来简化操作

set -- "$SCRIPT"

现在运行通过扩展获得的结果,SCRIPT通过在命令行上执行以下操作。

"$@"

这适用于您的输出SCRIPT包含多个单词,例如需要运行的自定义标志。由于这是在您当前的交互式 shell 中运行的,因此请确保要运行的命令不易受到代码注入的影响。您可以谨慎地采取一步并在子外壳中运行您的命令,以免您的父环境受到影响( "$@" ; )

于 2020-08-30T17:34:59.580 回答
3

如果脚本输出一个 shell 命令行来执行,那么正确的做法是:

eval "$("$SCRIPT")"

$($SCRIPT)只有在只使用分词和路径名扩展来完全评估命令时才会发生这种情况,这通常是一种罕见的情况。如果程序改为输出例如grep "Hello World"orcmd > file.txt那么您将需要eval或等效。

于 2020-08-30T17:52:58.880 回答
2

或者用于shellcheck disable=SCnnnn禁用警告并借此机会评论明确的意图,而不是通过隐藏在中间变量或参数数组后面来逃避检测。

#!/usr/bin/env bash

# shellcheck disable=SC2091 # Intentional execution of the output
"$("$SCRIPT")"

通过使用注释禁用 shellcheck,它阐明了意图并告诉有问题的代码不是错误,而是明智的实现设计选择。

于 2020-08-30T17:45:14.267 回答
1

你可以分两步完成

command_from_SCRIPT=$($SCRIPT)
$command_from_SCRIPT

它在 shellcheck 中很干净

于 2020-08-30T17:23:14.180 回答