$@ をコマンドに渡し、引用符を保持します。

$@ をコマンドに渡し、引用符を保持します。

私はgit動作を修正するために説明された方法を使用しようとしています。ここしかし、元の入力の引用符を失うことなくコンテンツを正しく配信する方法が$@困難です。

基本的に私はこれを持っています:

# foo.sh

#!/bin/bash
cmd=$1
shift
args=$@
if [ $cmd == "bar" ]; then args=('--baz' "${args[@]}"); fi
echo git $cmd ${args[@]}

ただし、実行すると必要ではなく./foo.sh bar -a "one two three"出力(したがって実行)されます。./foo.sh bar --baz -a one two./foo.sh bar --baz -a "one two"

$@他のコマンドに正しく渡して引用した引数を保持する方法がわかりません。可能ですか?どのように?

答え1

使用時に配列だと仮定"${args[@]}"しますが、そうではありません。args

配列になるには、args配列割り当てを使用して値を割り当てる必要があります。

args=( "$@" )

拡張時に配列の要素を個別に引用するには、${args[@]}拡張と同様に二重引用符を使用する必要があります"$@"

echo git "$cmd" "${args[@]}"

この簡単な例では、args別々の配列はまったく必要ありません。

#!/bin/sh

cmd=$1
shift

if [ "$cmd" = "bar" ]; then
   set -- --baz "$@"
fi

echo git "$cmd" "$@"

上記のコマンドは引用符を出力しませんecho。しかし、echo正確に2つの引数gitを取り、$cmdこの時点には多くの内容があるので安心してください。$@これは、シェルがコマンドを実行する前にコマンドから引用符を削除するためです。たとえば、echo "one two" three出力と比較できます。

目視検査のためにコマンドを出力するより良い方法は次のとおりです。

printf 'Arg: %s\n' git "$cmd" "$@"

これにより、個々の引数がprintf1行に印刷されます(文字列プレフィックスが付きますArg:)。

コマンド(または別の配列を使用している場合)gitは正しく実行されます(変数が意味があると仮定します(たとえば、オプション付きのサブコマンドを持たない通常のコマンド)。git "$cmd" "$@"git "$cmd" "${args[@]}"gitbar--baz

関連:

関連情報