1
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

[Zsh/Bash] ifを使わず終了ステータス(正常/異常)によって処理を分岐

1
Last updated at Posted at 2024-02-18

要約

以下のフローをワンライナーで実現しました。

  • コマンド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

参考

1
6
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?