gc
gitコミット/チェックアウトを区別できるスマートエイリアスを作成しています。
引数なしで呼び出すか、引数を使用して呼び出すとgc
git commitが実行されます。それ以外の場合は、git checkoutを実行します(追加のパラメータを持つフラグがある場合)。 gcの他のバリエーションが呼び出されると、予期しない操作を実行するのではなく、エラーを発生させたいと思います。-a
-m
b
これはこれまで私のシェル機能です。
gc() {
args=$@
commit=false
checkout=false
# Check flags
while getopts ":am:b" opt; do
case $opt in
a|m)
commit=true
;;
b)
checkout=true
;;
\?)
echo "Unknown flags passed."
return 1
;;
esac
done
shift "$((OPTIND-1))"
# Check number of arguments
if [[ "$#" == 0 ]]; then
commit=true
elif [[ "$#" == 1 ]]; then
checkout=true
else
echo "Too many arguments"
return 1
fi
# Finally run respective command
if [[ $commit == true && $checkout == true ]]; then
echo "Unable to ascertain which operation you would like to perform."
return 1
elif [[ $commit == true ]]; then
git commit "$args"
elif [[ $checkout == true ]]; then
git checkout "$args"
else
echo "Undefined behavior"
return 1
fi
}
しかし、これは正しく動作しません。いくつかの実験では、他の変数に割り当てることが根本的な原因であることがわかりましたが、なぜ$@
そして正確に何が間違っているのか理解できませんでした。
また、シェル関数を書くのは今回が初めてなので、私が犯した間違いを指摘してください。
答え1
$@
配列の場合は配列に割り当てます。
args=("$@")
その後、配列として使用します。
elif [[ $commit == true ]]; then
git commit "${args[@]}"
elif [[ $checkout == true ]]; then
git checkout "${args[@]}"
else
現在のコードで何が起こっているのかは、すべての個々のパラメータが単一の文字列として保存されることです。したがって、電話をかけると:
bc -a "foo bar"
次のように割り当てられますargs
。
args='-a foo bar'
次に、実行するのではなく、次のようにします。
git commit -a "foo bar"
あなたは以下を得ます:
git commit '-a foo bar'
その他の注意事項:
"$args[@]"
zshではorの"${(@)args}"
代わりに使用することもできますが、"${args[@]}"
bash / kshでは使用できません。"$args"
yashで動作しますが、ksh / bashではzsh
(接続された要素の最初の文字)とksh / bashと同じです。 zshではこれは機能しますが、空の要素がある場合は削除されます。"$args[*]"
$IFS
"${args[0]}"
$args
getopts
関数で使用するときは、事前に何かを追加する必要がありますlocal OPTIND OPTARG
(特に、OPTIND
または少なくとも初期化/設定解除)。 zshはOPTIND
他のシェルをエミュレートしないと自動的にこれを行いますが、ksh / bash / yashはそうではありません。関数内で使用する他の変数もローカル変数に設定する必要があります。- エラーはstderr(fd 2)に送信する必要があります
echo>&2 Too many arguments
。
答え2
他の答えはPOSIXではないので、ここに代替案があります。一時的に位置パラメータを粉砕するには、次のようにします。
s1=$(printf '%s\n' "$@")
その後、回復する準備ができたら、次の手順を実行します。
IFS='
'
set -- $s1
これは、引数に改行文字が含まれていないと仮定します。これにより、別の区切り文字を使用する必要があります。
注:最後の行には引用符がない変数が含まれています。これは、引用されていない変数が許容される数少ない場合(私の考えでは唯一の場合)の1つです。ユーザーが明示的に設定した場合ですIFS
。ユーザーは本質的に「はい、私がしていることを知っています。続けてください」と言います。 。