我想通过命令行调用一个工具。我需要生成用于动态调用的参数。此外,还需要向该工具提供许多参数。
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}
都将依次替换为该字符串的元素。