私がこれを行うときに私が期待したものを得ますbash
:
[ "a" == "a" ] && echo yes
それは私を与えましたyes
。
しかし、これをで行うとzsh
、次のようになります。
zsh: = not found
同じコマンド(/usr/bin/[
)が異なるシェルで異なる動作をするのはなぜですか?
私がこれを行うときに私が期待したものを得ますbash
:
[ "a" == "a" ] && echo yes
それは私を与えましたyes
。
しかし、これをで行うとzsh
、次のようになります。
zsh: = not found
同じコマンド(/usr/bin/[
)が異なるシェルで異なる動作をするのはなぜですか?
回答:
/usr/bin/[
どちらのシェルにもありません。Bashでは、組み込みのtest
/ [
コマンドを使用しており、同様にzshでも使用しています。
違いはあるのzshも有する=
拡張:=foo
パスに展開foo
実行します。つまり==
、で呼び出さ=
れたコマンドを見つけようとするものとして扱われますPATH
。そのコマンドは存在しないため、エラーが発生します
zsh: = not found
(実際にを使用していても、同じことが起こります/usr/bin/[
)。
あなたは、することができます使用し==
、あなたが本当にしたい場合はこちら。これは、zshで期待どおりに機能します。
[ "a" "==" "a" ] && echo yes
引用は=word
拡張の実行を妨げるためです。でequals
オプションを無効にすることもできますsetopt noequals
。
ただし、次のいずれかをお勧めします。
=
のPOSIX互換同等性テストを使用します。または[[
==
さらに良いです。一般的には、内部に特別な解析ルールを設定することで、この種の問題(およびその他の問題)を回避することを含め、すべての点で優れており、安全です。[[
[
とは[[
?(Googleで検索すると、検索[ vs [[
結果vs
のみが表示されます、LOL)
[[
はどちらの場合もより広い範囲のテストをサポートし、変数や演算子などを引用する必要をなくすカスタム解析ルールを備えています。特にBashまたはzshを使用している場合は、を使用してください[[
。移植可能なスクリプトを作成している場合は、POSIX互換の[
/ test
コマンドに書き込みます(実行中のシステムで実際のコマンドである場合とそうでない場合があります)。
[[
そこに使用して、存在を忘れてください[
。
[[
機能は異なります。これを試してみてくださいfor f in *; do [ -e "$f" ] && for a in f d h p S b c; do [ "-$a" "$f" ] && for p in r w x u g; do [ "-$p" "$f" ] || p=-; a=$a$p; done && break; done && printf "%s:\t%s\n" "$a" "$f"; done
。
=
/ ==
間違いなく一つのケースである[[
よりも良好ではない[
として、[[ a == b ]]
ある「」「B」のパターンと一致しないし、ではない「」「B」に等しく、あなたが期待通り。それは[[ $a == "$b" ]]
、例えばあなたが書く必要があることを意味します。少なくとも、この[
コマンドを使用すると、コマンドの解析がどのように機能するかがわかっていれば[ "$a" = "$b" ]
、他のコマンドのようにsplit + glob演算子を回避するためにそれを記述する必要があることがわかります。これを念頭に置き、-aまたは-oを使用しない場合[
は、POSIX準拠の実装で安全です。
[
bashおよびzshのシェル組み込みコマンドです。
$ type [
[ is a shell builtin
以下からのシェルの組み込みコマンドのドキュメント:
組み込みコマンドはシェル自体に含まれています。組み込みコマンドの名前が単純コマンドの最初の単語として使用されている場合(単純コマンドを参照)、シェルは別のプログラムを呼び出さずにコマンドを直接実行します。組み込みコマンドは、別個のユーティリティで取得することが不可能または不便な機能を実装するために必要です。
公式ドキュメント($ help test
)でのみ使用できます=
:
STRING1 = STRING2
文字列が等しい場合はTrue。
したがって、正しい式は次のようになります。
$ [ "a" = "a" ] && echo yes
yes
何が起こるかというと、bashは少し厳密ではありません。での==
オペレーターのサポートは[
bash拡張機能のようであり、使用することはお勧めしません。
string1 == string2
string1 = string2
文字列が等しい場合はTrue。[[コマンドと一緒に使用すると、上記のようにパターンマッチングが実行されます(条件付き構成体を参照)。
'='は、POSIX準拠のテストコマンドで使用する必要があります。
を使用する==
場合は、次の[[
キーワードを使用する必要があります。
$ [[ "a" == "a" ]] && echo yes
yes
覚えておいてください[[
あまりポータブルである(POSIXではありません)。しかし、bashとzshの両方がサポートしています。
両方のシェルでは、bash
とzsh
、[
ユーティリティは、シェルの組み込みです。これはそのツールのシェル実装であり、バイナリよりも優先的に使用されます/usr/bin/[
。異なる結果は、実装によって異なります。
ではbash
、[
ユーティリティは複合コマンドCONDITIONAL EXPRESSIONS
として受け入れます[[
。bashs manページによると、両方=
と==
有効です。
string1 == string2
string1 = string2
True if the strings are equal. = should be used with the test command for POSIX
conformance.
ではzsh
、[
ユーティリティはPOSIXとその拡張が指定されている場合、それらを実装しようとします。POSIXテストユーティリティの仕様全く存在しない==
オペレータ定義されます。
$PATH
が検索されます。そして、アウェイの==
有効なtest
構文ではありません/usr/bin/[
。ただ、=
結構です。