私はちょうど何の違いを疑問に思いました
[[ $STRING != foo ]]
そして
[ $STRING != foo ]
それとは別に、後者はposix準拠であり、shにあり、前者はbashにある拡張機能です。
私はちょうど何の違いを疑問に思いました
[[ $STRING != foo ]]
そして
[ $STRING != foo ]
それとは別に、後者はposix準拠であり、shにあり、前者はbashにある拡張機能です。
回答:
いくつかの違いがあります。私の意見では、最も重要なものは次のとおりです。
[
Bashやその他の多くの最新のシェルに組み込まれています。組み込み[
はtest
、終了の追加要件と似ています]
。組み込みコマンド[
とは、test
機能を模倣/bin/[
し、/bin/test
その限界と一緒にスクリプトが下位互換性になるように。元の実行可能ファイルは、主にPOSIX準拠と後方互換性のためにまだ存在しています。type [
Bashでコマンドを実行すると[
、デフォルトで組み込みとして解釈されます。(注:PATHwhich [
で実行可能ファイルのみを検索し、に相当します)type -p [
[[
互換性がそれほど高くないため、どのような/bin/sh
ポイントでも機能するとは限りません。だから、[[
より近代的なバッシュ/ Zshの/のkshオプションがあります。[[
、シェルに組み込まれており、従来の要件を持っていない、あなたはに基づいて単語の分割を心配する必要はありませんIFSのスペースを文字列に評価された変数に台無しに変数。したがって、変数を二重引用符で囲む必要はありません。ほとんどの場合、残りはより優れた構文です。より多くの違いを見るには、FAQの回答へのこのリンクをお勧めします:testと[と[[の違いは何ですか?。実際、bashスクリプトについて真剣に考えているのであれば、FAQ、Pitfalls、およびGuide を含むwiki全体を読むことをお勧めします。 ガイドセクションのテストセクションでも、これらの違いについて説明します。また、移植性を心配する必要がない場合、作成者がより良い選択であると考える理由についても説明します。主な理由は次のとおりです。[[
< >
入力のリダイレクト、ファイルを上書きすることによってすることができます本当に混乱いくつかのものをアップとして評価を取得していない彼らのために順番にバックスラッシュとします。これもビルトインに戻り[[
ます。[(テスト)が外部プログラムである場合、シェルは、それが評価された方法で例外を作成しなければならないであろう<
と>
する場合にのみ/bin/test
、本当に意味を成さないであろう、と呼ばれています。要するに:
[はbash Builtinです
[[]]はbash キーワードです
キーワード:キーワードはビルトインによく似ていますが、主な違いは特別な解析ルールがキーワードに適用されることです。たとえば、[はbashビルトインで、[[はbashキーワードです。どちらもテスト用に使用されますが、[[は組み込みではなくキーワードであるため、いくつかの特別な解析ルールの恩恵を受けます。
$ [ a < b ]
-bash: b: No such file or directory
$ [[ a < b ]]
最初の例は、bashがファイルbをコマンド[a]にリダイレクトしようとするため、エラーを返します。2番目の例は、実際にあなたが期待することを行います。文字<には、ファイルリダイレクト演算子の特別な意味はなくなりました。
ソース:http : //mywiki.wooledge.org/BashGuide/CommandsAndArguments
[
POSIXシェルコマンドです。組み込みの必要はありません。]
構文はバランスが取れるように、そのコマンドが探す引数にすぎません 。このコマンドは、終了を検索しないtest
ことを除いて、同義語です。test
]
行動の違い
Bash 4.3.11のいくつかの違い:
POSIX対Bash拡張機能:
通常コマンドvsマジック
[
奇妙な名前の通常のコマンドです。
]
は単なる引数であり[
、それ以上の引数が使用されないようにします。
Ubuntu 16.04には実際には/usr/bin/[
coreutilsが提供する実行可能ファイルがありますが、bashの組み込みバージョンが優先されます。
Bashがコマンドを解析する方法に変更はありません。
特に、<
リダイレクトで&&
あり、||
複数のコマンドを連結( )
し\
、でエスケープされない限りサブシェルを生成し、単語の展開は通常どおり行われます。
[[ X ]]
X
魔法のように解析される単一の構成体です。<
、&&
、||
および()
特別に処理し、単語分割ルールは異なるされています。
また、などの違いも=
あり=~
ます。
Basheseの場合:[
は組み込みコマンドであり[[
、キーワードです:https : //askubuntu.com/questions/445749/whats-the-difference-between-shell-builtin-and-shell-keyword
<
[[ a < b ]]
:辞書編集の比較[ a \< b ]
: 同上。\
その他のコマンドと同様にリダイレクトが必要です。バッシュ拡張。expr a \< b > /dev/null
:POSIX同等²、参照:https : //stackoverflow.com/questions/21294867/how-to-test-strings-for-lexicographic-less-than-or-equal-in-bash/52707989#52707989&&
そして ||
[[ a = a && b = b ]]
:真、論理、[ a = a && b = b ]
:構文エラー、&&
ANDコマンド区切りとして解析cmd1 && cmd2
[ a = a -a b = b ]
:同等ですが、POSIX³で非推奨[ a = a ] && [ b = b ]
:POSIXおよび信頼できる同等物(
[[ (a = a || a = b) && a = b ]]
:偽[ ( a = a ) ]
:構文エラー、()
サブシェルとして解釈されます[ \( a = a -o a = b \) -a a = b ]
:同等()
ですが、POSIXでは非推奨です{ [ a = a ] || [ a = b ]; } && [ a = b ]
POSIXで同等の5単語分割と展開時のファイル名生成(split + glob)
x='a b'; [[ $x = 'a b' ]]
:true、引用符は不要x='a b'; [ $x = 'a b' ]
:構文エラー、展開先 [ a b = 'a b' ]
x='*'; [ $x = 'a b' ]
:現在のディレクトリに複数のファイルがある場合の構文エラー。x='a b'; [ "$x" = 'a b' ]
:POSIXと同等=
[[ ab = a? ]]
:true 。パターンマッチングを行うためです(* ? [
魔法です)。現在のディレクトリ内のファイルに展開しません。[ ab = a? ]
:a?
globが展開します。したがって、現在のディレクトリ内のファイルに応じて、trueまたはfalseになります。[ ab = a\? ]
:glob展開ではなくfalse=
そして==
、両方で同じである[
と[[
、しかし==
バッシュの拡張機能です。case ab in (a?) echo match; esac
:POSIXと同等[[ ab =~ 'ab?' ]]
:false 4、魔法を失う''
[[ ab? =~ 'ab?' ]]
:true=~
[[ ab =~ ab? ]]
:true、POSIX 拡張正規表現一致、?
glob展開しない[ a =~ a ]
: 構文エラー。同等のbashはありません。printf 'ab\n' | grep -Eq 'ab?'
:POSIX同等(単一行データのみ)awk 'BEGIN{exit !(ARGV[1] ~ ARGV[2])}' ab 'ab?'
:POSIXと同等。推奨事項:常に使用します[]
。
[[ ]]
私が見たすべての構成体にPOSIXに相当するものがあります。
あなたを使用する[[ ]]
場合:
[
は、奇妙な名前を持つ通常のコマンドであり、特別なセマンティクスは含まれていません。[[...]]
¹Kornシェルの同等のコンストラクトに触発された
²が、a
or b
(+
orなどindex
)の一部の値では失敗し、10進整数の場合は数値比較をa
行いb
ます。expr "x$a" '<' "x$b"
両方で動作します。
³ものいくつかの値のために失敗したa
かb
のような!
、または(
。
bash 3.2以降の4および提供されているbash 3.1との互換性は有効ではありません(などBASH_COMPAT=3.1
)
5(とここでグルーピングものの{...;}
代わりにコマンド群(...)
として不要サブシェルを実行することになる)が必要でない||
と&&
(とは対照的に、シェル演算子||
及び&&
[[...]]
オペレータ又は-o
/ -a
[
オペレータ)は等しい優先順位を有します。だから[ a = a ] || [ a = b ] && [ a = b ]
同等になります。
printf 'ab' | grep -Eq 'ab?'
内で使用するにはif [ … ]
?
if ( printf 'ab' | grep -Eq 'a' ); then echo 'a'; fi
。[]
はのようなコマンドgrep
です。()
そのコマンドには必要ないかもしれませんが、よく|
わかりません:のために追加したのは、Bashが物事をどのように解析するかに依存します。なかった場合は、|
ちょうどあなたが書くことができると確信していますif cmd arg arg; then
。
()
に思えるん:stackoverflow.com/questions/8965509/...
シングルブラケットすなわち[]
、条件式を囲んでに準拠POSIXシェルです。
二重括弧つまり[[]]
、これはbashのや他のシェル(zshの、kshの)によってサポートされている標準のPOSIXバージョンの強化(または拡張)バージョンです。
bashのでは、我々が使用する数値比較のためにeq
、ne
、lt
およびgt
比較のために二重括弧で、我々は使用することができ==
、!=
、<,
そして>
文字通り。
[
testコマンドの同義語です。シェルに組み込まれている場合でも、新しいプロセスを作成します。[[
これは新しい改良バージョンであり、プログラムではなくキーワードです。 例えば:
[ var1 lt var2] #works
[ var1 < var2] #error: var2 No such file or directory
[ var1 \< var2] #works with escape
[[ var1 < var2]] #works
if
ステートメントのコンテキストなどで、括弧をまったく使用しないことを考えて