
私にはできる
$ [ -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で定義完全にポータブルである必要があります。
は、 (のいくつかのバージョンにも存在する機能[[ ]]
です。ksh
bash
すべて現代のもの) や、zsh
おそらく他のシェルにも存在しますが、sh
やdash
、または他のさまざまなより単純なシェルには存在しません。
したがって、スクリプトを移植可能にするには、[ ]
、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
== 条件(テストコマンドの場合もあります)の場合、コマンドを実行します。
したがって、間の移植性[
と[[
使用[
のみを目的としています。
if
POSIX と互換性があります。したがって、どちらかを選択する必要がある場合は[
、if
タスクと予想される動作を確認してください。
答え4
移植性のためにはtest
/ を使用してください[
。ただし、移植性が必要ない場合は、自分自身とスクリプトを読む他の人の安全のために を使用してください[[
。:)
以下もWhat is the difference between test, [ and [[ ?
参照BashFAQ。