动态生成的参数 未提供给工具

动态生成的参数 未提供给工具

我想通过命令行调用一个工具。我需要生成用于动态调用的参数。此外,还需要向该工具提供许多参数。

COMMAND=""
for i in $VERSIONS; do
    COMMAND+=" '../apache-maven-$i/bin/mvn clean'"
done

所以现在我想使用生成的参数列表(从上面)调用该工具,如下所示:

hyperfine --export-markdown ../results.md -w 5 $COMMAND

但不幸的是,这会产生以下结果:

Benchmark #1: '../apache-maven-3.0.5/bin/mvn
Error: Command terminated with non-zero exit code. Use the '-i'/'--ignore-failure'
     option if you want to ignore this. Alternatively, 
use the '--show-output' option to debug what went wrong.

我的假设是创建的参数$COMMAND不会被识别为多个参数。它被视为单个参数,这是错误的。如果我打印出整个命令行并手动将其复制到 bash 行中,则执行效果会很好。

hyperfine --export-markdown ../results.md -w 5 '~/tools/apache-maven-3.8.2/bin/mvn clean' '~/tools/apache-maven-3.8.1/bin/mvn clean' '~/tools/apache-maven-4.0.0-alpha-1-SNAPSHOT/bin/mvn clean'

在生成用于在 Bash 中调用其他工具的多个参数时,是否需要考虑一些特殊事项?

答案1

这里的问题是单引号正在成为您想要进行基准测试的命令的一部分hyperfine

相反,我们假设您想要收集数组中的所有命令,然后使用它。

commands=()
for version in "${versions[@]}"; do
    commands+=( "../apache-maven-$version/bin/mvn clean" )
done

hyperfine --warmup 5 --export-markdown ../results.md "${commands[@]}"

在上面的代码中,我假设这versions是一个数组,例如

versions=( '3.8.1' '3.8.2' '4.0.0-alpha-1-SNAPSHOT' )

的扩展"${commands[@]}"将是您想要进行基准测试的命令,每个命令都单独引用。

不过,可以直接hyperfine使用你的数组。versions

(
        IFS=,
        hyperfine               \
                --warmup 5      \
                --export-markdown ../results.md                 \
                --parameter-list version "${versions[*]}"       \
                '../apache-maven-{version}/bin/mvn clean'
)

或者,如果您更喜欢简短的选项和长的俏皮话,

( IFS=, ; hyperfine -w 5 --export-markdown ../results.md -L version "${versions[*]}" '../apache-maven-{version}/bin/mvn clean' )

同样,这假设它versions是一个像我们上面所示的数组。设置IFS为逗号会使"${versions[*]}"版本字符串扩展为逗号分隔的字符串。在子 shell 中执行此操作可以避免IFS在调用 shell 中进行修改。

当您将逗号分隔的字符串与 一起使用时--parameter-list placeholder,作为操作数给出的命令字符串中出现的任何字符串{placeholder}都将依次替换为该字符串的元素。

相关内容