bash シェル間および他のシェル間では、test または [ または [[ の方が移植性が高いですか?

bash シェル間および他のシェル間では、test または [ または [[ の方が移植性が高いですか?

私にはできる

$ [ -w /home/durrantm ] && echo "writable"
writable

または

$ test -w /home/durrantm && echo "writable"
writable

または

$ [[ -w /home/durrantm ]] && echo "writable"
writable

私は 3 番目の構文を使用するのが好きです。これらは、すべての点で、またすべての否定ケースとエッジ ケースで同等ですか? たとえば、Ubuntu と OS X の bash 間、または 4.0 より前/後などの古い/新しい bash バージョン間で移植性に違いはありますか? また、どちらも式を同じように展開しますか?

答え1

はい、違いはあります。最も持ち運びやすいのはtestまたは です[ ]。これらはどちらもPOSIXtest仕様

このif ... fi構造はまたPOSIXで定義完全にポータブルである必要があります。

は、 (のいくつかのバージョンにも存在する機能[[ ]]です。kshbashすべて現代のもの) や、zshおそらく他のシェルにも存在しますが、shdash、または他のさまざまなより単純なシェルには存在しません。

したがって、スクリプトを移植可能にするには、[ ]testまたは を使用しますif ... fi

答え2

[はコマンドの同義語でありtest、同時にbash組み込み[[別々のコマンドです。しかし、bash キーワード一部のバージョンでのみ動作します。そのため、移植性の観点から、単一[]またはtest

[ -w "/home/durrantm" ] && echo "writable"

答え3

ただし、これは建設[] && cmdと同じではないことに注意してくださいif .. fi

[] && cmd場合によっては、その動作は非常に似ているため、の代わりにを使用できます。ただし、場合によってはのみです。条件を満たす場合に実行するコマンドが複数ある場合や、ロジックに注意するif .. fi必要がある場合は、注意が必要です。if .. else .. fi

いくつか例を挙げます。

[ -z "$VAR" ] && ls file || echo wiiii

同じではありません

if [ -z $VAR ] ; then
  ls file
else
  echo wiii
fi

lsが失敗すると、echoが実行され、 では発生しないためですif

もう一つの例:

[ -z "$VAR" ] && ls file && echo wiii

は同じではありません

if [ -z "$VAR" ] ; then
   ls file
   echo $wiii
fi

この構造は同じように動作しますが

[ -z "$VAR" ] && { ls file ; echo wiii ; }

;エコーの後は重要であり、そこに存在する必要があることに注意してください。

上の文を要約すると、

[] && cmd== 最初のコマンドが成功したら、次のコマンドを実行します

if .. fi== 条件(テストコマンドの場合もあります)の場合、コマンドを実行します。

したがって、間の移植性[[[使用[のみを目的としています。

ifPOSIX と互換性があります。したがって、どちらかを選択する必要がある場合は[ifタスクと予想される動作を確認してください。

答え4

移植性のためにはtest/ を使用してください[。ただし、移植性が必要ない場合は、自分自身とスクリプトを読む他の人の安全のために を使用してください[[。:)

以下もWhat is the difference between test, [ and [[ ?参照BashFAQ

関連情報