そのようなものを使いたい
if [[ ! -z "$ENV" && $ENV == 'production' ]]; then echo "production"; else echo "dev"; fi
しかしBusyBoxでは機能しません:(
sh: 1: [[: not found
ANDまたはORの組み合わせは、busyboxへのIFステートメントでは機能しません。
古い[
構文を使用できます
if [ -n "$ENV" -a "$ENV" = 'production' ]
(読みやすいので、-n
ではなく! -z
を使用したことに注意してください。ただし、同じことです)。
または、文字列に値を強制することで、さらに古い構文に簡略化できます。
if [ "x$ENV" = 'xproduction' ]
最後に、-n
テストは実際には必要ないかもしれません。
if [ "$ENV" = 'production' ]
[[...]]
は、bash
およびzsh
でもサポートされているKornシェル構造ですが、標準のsh
のものではありません(他のシェルではサポートされていません)。
busybox
sh
は、ash
のPOSIX仕様のサブセットを実装するsh
に基づいており(POSIXロケールでは、ほとんどの部分が準拠しており)、特に拡張機能はほとんどありません。
2019編集。 kshの[[...]]
の限られたサブセットは、ASH_TEST
とASH_BASH_COMPAT
、およびyash
のはるかに大きなサブセットでビルドされた場合、busybox ashでもサポートされるようになりました。
いずれの場合でも、sh
スクリプトを作成するときは、POSIXのsh
仕様に固執する必要があります。 [[...]]
を使用するスクリプトは、ksh
、bash
、またはzsh
を明示的に呼び出す必要があります。 bash
もまた、ほとんどがPOSIX sh互換のシェルですが、拡張機能が多くなっています(これを含む)。
xが空ではなく、production
と等しいかどうかのテストはほとんど意味がありません。 x== production
の場合、明らかに空ではありません。
POSIXシェルとユーティリティで文字列比較を行います。いくつかのオプションがあります。この場合の最も明白なオプションは次のとおりです。
[
ユーティリティ(別名test
)は、通常シェルに組み込まれています。
if [ "$var" = production ]; then
echo PROD
fi
case
構文:
case $var in
production) echo PROD;;
"") echo EMPTY;;
*) echo non-PROD;;
esac
ここで、nounset
オプションが有効になっている場合に、変数を逆参照する前に、変数がsetであることを確認します(空ではない)。 set -u
またはset -o nounset
、または#! /bin/sh -u
をシバン行として使用)、そうでない場合、[ "$ENV" = production ]
は、$ENV
が設定されていない場合にシェルを終了します。それを行うには、次のようにします。
if [ "${var+set}" = set ] && [ "$var" = production ]; then
echo PROD
fi
(-a
[
AND演算子は非推奨で信頼性が低いため、避けてください)。
それを行うためのより良い、より標準的な方法は次のとおりです。
if [ "${var-}" = production ]; then
echo PROD
fi
nounset
は、${var+string}
または${var-string}
拡張ではトリガーされません。 ${var-}
は、変数が設定されている場合は$var
の内容に、それ以外の場合は空の文字列に展開されます。
その他の注意事項:
$ENV
は、sh
の特殊変数です。対話的に開始すると、初期化を読み取るファイルへのパスとして使用されます(bash
の~/.bashrc
に相当)。他の目的には使用しないでください。
一部の古いUnix Shellスクリプト記述では、[ "x$var" = xproduction ]
または[ production = "x$var" ]
を使用して文字列を比較することが推奨されています。これは、[
、$var
、!
のような(
のいくつかの値によって混乱した、-n
およびtest
ユーティリティのいくつかの古いバージョンのバグを克服するためです。最新のシステムでは必要ありませんが、非常に古いシステムでは注意が必要です。いずれの場合でも、case
構成にはこの種の問題はありません。
文字列比較を実行できる他のPOSIXユーティリティには、expr
とawk
があります。
awk_equal() { awk 'BEGIN{exit(!(""ARGV[1] == ""ARGV[2]))}' "$1" "$2"; }
expr_equal() { expr "x $1" = "x $2" > /dev/null; }
if awk_equal "$var" production; then
echo PROD
fi
if expr_equal "$var" production; then
echo PROD
fi
awk
の値の前に""
を付加する必要があることに注意してください。そうしないと、文字列比較(そうでなければ1
は01
または1e0
と等しいと見なされます)、およびx
のexpr
は、同じ理由でexpr
演算子の値の問題を回避します。 。
awk
とexpr
の両方(少なくともPOSIXly)では、これらは実際にはequality演算子ではありませんが、2つのオペランドのソート順が等しいかどうかのテストであり、必ずしも同じではない場合があります。たとえば、5月のシステムでは、②も③もソート順が定義されていないため、expr_equal ② ③
はtrueを返します。 awk
、gawk
、busybox mawk
などの一部のawk
実装は、POSIX要件を無視し、代わりに単純なバイト間比較を行います。
いずれにせよ、ここで[
やcase
よりもそれらを好む理由は考えられません。