今まで 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” は同じプロセス環境で動く
{ ... }
ではなく、サブシェルを起動する( ... )
でも良いということなので、新規プロセス起動のオーバーヘッドが問題にならないのであれば、子プロセス内でローカル関数を定義すれば、より構造化されたシェルスクリプトが書ける。