LoginSignup
3
3

More than 5 years have passed since last update.

シェル内で使うフラグのイディオム

Last updated at Posted at 2015-01-15

今まで if test "$is_darwin" == "true" のようにやっていたが、これは冗長だろう。alias を使う方法も考えたが、こと真偽値で判定する場合についてはリターンコード(エラーコード)がそのまま使えるのだから、以下のような書き方が、最も汎用性があり、なおかつ簡潔だろう。

#!/bin/sh

is_darwin() { test "$(uname)" == "Darwin"; }
is_linux()  { test "$(uname)" == "Linux"; }

if is_darwin
then
  echo "This is Darwin."
else
  echo "This is not Darwin."
fi

if ! is_linux
then
  echo "This is not Linux."
else
  echo "This is Linux."
fi

判定は動的ですし。

#!/bin/sh
# -*- coding: utf-8 -*-

at_home() { test "$PWD" == "$HOME"; }

cd /
if at_home
then
  echo "Here $PWD, I'm at home."
else
  echo "Here $PWD, I'm out of home."
fi

cd
if at_home
then
  echo "Here $PWD, I'm at home."
else
  echo "Here $PWD, I'm out of home."
fi

あとは predicate のネーミングルールかな。Ruby のように識別子に ? が使えるとカッコいいのだが、そうも行かない。Lisp 畑の人であれば、postfix に p かな。

darwinp() { test "$(uname)" == "Darwin"; }
linuxp()  { test "$(uname)" == "Linux"; }

if darwinp || linuxp
then
  echo "This is a *NIX environment."
fi

いや、若干 snob で、いやらしいかな?

Note: 問題があるとすれば、Bash では、変数がローカルのダイナミックスコープを持てるのと違って、関数にはスコープがグローバルスコープしかないので、関数内にローカルな関数が定義できないことですね。

Note: いや、そんなことはないですね。bash(1) を見ると、関数にする “Compound Commands” は同じプロセス環境で動く { ... } ではなく、サブシェルを起動する ( ... ) でも良いということなので、新規プロセス起動のオーバーヘッドが問題にならないのであれば、子プロセス内でローカル関数を定義すれば、より構造化されたシェルスクリプトが書ける。

3
3
0

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
3
3