gでgit status、続く引数があったらgitに渡すシェルスクリプトを実装したメモ

スポンサーリンク

最近コーディング時に腕の疲れを感じるようになってきたので、アホみたいでもなるべく短いaliasを.bashrcや.gitconfigに設定しています。

で、今回実装したのが、gitで一番よく使うのがgit statusなので
g → git status
g [引数] → git [引数]
となるシェルスクリプト。
これがいくつか詰まりどころがあったのでシェルスクリプトに関する理解メモとして残します。

ソースはこちら。
https://github.com/yoshi-self/dotfiles/blob/master/scripts/misc/g.sh

以下自分が詰まったところについて。

クオートはコマンドに渡る前にBashで処理される

g commit -m ‘Add hoge.txt’
のようなコマンドを実行した場合、”の処理はコマンドに渡る前にBashで処理されるので、スクリプトに渡ってくる引数は順番に
commit
-m
Add hoge.txt
のようになり、クォーテーションで囲まれていたかどうかはわかりません。

関数に配列を渡せない?

グローバルで
args=(“$@”)
のようにすると引数を配列に変えることができるのですが、これを関数に渡して配列として回す手段がどうしても見つかりませんでした。
stackoverflow先生にも

How to pass an array argument to the Bash script
>Bash arrays are not “first class values” — you can’t pass them around like one “thing”.

というように書かれていたので、無理なのかなーと思いグローバルでそのまま処理を書くことに。(自分の不勉強で本当はできるんでしょうか?)

もう一度クオートし直す

渡ってきた引数をそのまま繋げてコマンドにすると
git commit -m Add hoge.txt
のようになり、メッセージの部分がクオートされていないのでgitにエラー出されます。
なので、逆にクオートはコマンド実行前に解釈されるということは
git ‘commit’ ‘-m’ ‘Add hoge.txt’
のように全ての引数をクオートしてしまえばいいと思い、引数の配列を回して全て”で囲います。

最後の実行にはevalを使う

で、できた変数commandに「git ‘commit’ ‘-m’ ‘Add hoge.txt’」のような文字列が格納された状態で
$command
とやるとこのときはクオートを展開してくれないみたいで、”commit”なんてコマンドはないみたいなエラーになります。
これは
eval $command
としてevalを通して実行することで解決しました。

以上。もしかしたらエスケープされたメタ文字とかが渡ってきたときに何か変な挙動をするかもしませんが、とりあえずは使えてます。

コメント

タイトルとURLをコピーしました