
スクリプトを書くとき、通常、次の構文を使用すると、次に何が起こるのかが正しくないことを理解しやすくなります。
if [ ! "$1" = "$2" ]; then
一部の人々は、次の方法が良いと言います。
if [ "$1" != "$2" ]; then
問題は、なぜ、どのような違いがあるのか尋ねたとき、誰も答えができないようだということです。
それでは、これら2つの構文の間に違いはありますか?一方が他より安全ですか?それともこれは単に好み/習慣の問題ですか?
答え1
[ ! "$a" = "$b" ]
装飾/デフォルト設定パラメータに加えて、特別な場合に失敗する実装率が理由の1つである可能性があります[ "$a" != "$b" ]
。
実装が次の場合、どちらの場合も安全でなければなりません。POSIXアルゴリズムしかし、今日(この記事を書く時点である2018年初め)でも、まだ失敗した実装があります。たとえば、次のようになりますa='(' b=')'
。
$ (a='(' b=')'; busybox test "$a" != "$b"; echo "$?")
0
$ (a='(' b=')'; busybox test ! "$a" = "$b"; echo "$?")
1
0.5.9より前のバージョン(例:Ubuntu 16.04のdash
0.5.8):sh
$ a='(' b=')' dash -c '[ "$a" != "$b" ]; echo "$?"'
0
$ a='(' b=')' dash -c '[ ! "$a" = "$b" ]; echo "$?"'
1
(0.5.9で修正されました。参照)https://www.mail-archive.com/[Eメール保護]/msg00911.html)
これらの実装ではこれをそのまま処理[ ! "(" = ")" ]
( "text" が空文字列かどうか[ ! "(" "text" ")" ]
テスト ) するのに対し、 POSIX ではこれを義務化します ("x" と "y" が等しいかテスト)。この場合、誤ったテストを実行するため、これらの実装は失敗します。[ ! "text" ]
[ ! "x" = "y" ]
他の形式もあります。
! [ "$a" = "$b" ]
これにはPOSIXシェルが必要です(以前のBourneシェルでは使用できませんでした)。
気づく一部の実装[ "$a" = "$b" ]
では(and)問題も発生しました。[ "$a" != "$b" ]
そしてまだSolaris 10の[
組み込み機能/bin/sh
(Bourneシェル、のPOSIXシェル/usr/xpg4/bin/sh
)と同じです。そのため、次の内容が表示されます。
[ "x$a" != "x$b" ]
古いシステムに移植したいスクリプトから。
答え2
構文はエラーが発生しやすいx != y
ため、より良いです! x == y
。さまざまな言語の演算子の優先順位を理解する必要があります。構文は、対優先順位に従って、また! x == y
はと解釈できます。!(x == y)
(!x) == y
!
=
たとえば、c++
否定では!
比較/関係演算子の前に表示されます。 ==
したがって、次のコードがあります。
#include<iostream>
using namespace std;
int main()
{
int x=1, y=2;
if( x != y ) cout<<"true"<<endl; else cout<<"false"<<endl;
if( ! x == y ) cout<<"true"<<endl; else cout<<"false"<<endl;
if( !( x == y ) ) cout<<"true"<<endl; else cout<<"false"<<endl;
if( (!x) == y ) cout<<"true"<<endl; else cout<<"false"<<endl;
}
返品
true
false
true
false
awk
Unixの世界で一般的に使用されているツールを含む、他の多くの言語でも同様の動作を見ることができます。
一方、x != y
検証されたモデルとしてオペレータを一つに集めても混乱は発生しません。また、技術的には !=
一般的に2人ではなく1人の演算子があるため、評価は個別に比較して否定するよりもやや高速です。したがって、両方の構文はbashで使用できますが、いくつかのx != y
標準ロジックに従うコードが読みやすくなりやすいため、この構文に従うことをお勧めします。
答え3
これは非常に視点に応じて、「答え」は、個人の脳がどのようにつながっているかによって大きく左右されます。実際には意味上NOT ( A == B )
同じですが、(A != B )
1つはよりよく知っているかもしれませんが、もう1つはもっとよく知っているかもしれません。また、状況によって異なります。たとえば、フラグを設定すると、他の構文よりも1つの構文を使用すると、意味がより明確になります。
if NOT ( fileHandleStatus == FS_OPEN )
相対的な
if ( fileHandleStatus != FS_OPEN )