要約
以下のフローをワンライナーで実現しました。
-
コマンドAが正常終了 ->コマンドBを実行 -
コマンドAが異常終了 ->コマンドCを実行
Zsh:
コマンドA && {コマンドB; true} || コマンドC
Bashにも対応:
コマンドA && { コマンドB; true; } || コマンドC
※ 問題点については追記を参照
活用例
.zshrcのGitのエイリアスで、
- 何かステージングしてる時は、直前のコミット上書き
git commit --amend --no-edit
- 何もステージングしてない時は、直前のコミットメッセージ編集
git commit --amend
というのが作れたらいいなと考えました。
調べてみると、ステージングの判定は以下で可能でした。
git diff --cached --quiet
-
git diff --cached... ステージング中の差分を見る -
--quiet... 標準出力はせず、差分があれば異常終了で知らせる
最後にこれらを冒頭の型にはめれば完成です。
git diff --cached --quiet && {git commit --amend; true} || git commit --amend --no-edit
仕組み
A && B
↑これは、Aが正常終了したらBを実行します。
A || B
↑これは、Aが異常終了したらBを実行します。
A && B || C
↑これで、Aが正常終了ならB、異常終了ならCを実行できます。
ただ、ひとつ問題があります。Bが異常終了した時にもCが実行されてしまうことです。
そこで、trueコマンドという、常に正常終了するコマンドを利用します。
A && {B; true} || C
これならBが異常終了しても、その後に実行されるtrueが必ず正常終了するので、Cが実行されることはありません。
追記 - 問題点
コメントで指摘をいただきました。
この方法はコマンドBが異常終了したとき、コマンドライン全体が正常終了になります。
素直にifを使ったワンライナーでは、そのような問題は起きません。
if コマンドA; then コマンドB; else コマンドC; fi
参考