動的に生成されたパラメータがツールに提供されない

動的に生成されたパラメータがツールに提供されない

コマンドラインでツールを呼び出したいです。動的呼び出しのパラメーターを生成する必要があります。また、ツールに複数のパラメータを提供する必要があります。

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[*]}"バージョン文字列はコンマで区切られた文字列に展開されます。サブシェルでこれを行うと、IFS呼び出しシェルで変更が防止されます。

カンマで区切られた文字列を使用すると、--parameter-list placeholderオペランドとして指定されたコマンド文字列で、その文字列が順番に{placeholder}その文字列の要素に置き換えられます。

関連情報