回答:
ではbash
、2つの引数のコンテキストtest
コマンドを使用-a file
し-e file
て、と同じです。しかし-a
、2項演算子でもあるため、両者には多少の違いがあります。
-e
単項はPOSIXで定義されていますが、単項は定義されて-a
いません。POSIXは-a
バイナリのみを定義します(テスト POSIXを参照)。
POSIXは、3つの引数のtest
動作を定義します。
3つの引数:
$ 2がバイナリプライマリの場合、$ 1と$ 3のバイナリテストを実行します。
$ 1が '!'の場合、$ 2と$ 3の2つの引数のテストを否定します。
$ 1が '('で$ 3が ')'の場合、$ 2の単項検定を実行します。XSIオプションをサポートしないシステムでは、$ 1が '('で$ 3が ')'の場合の結果は不定です。
それ以外の場合、不特定の結果が生成されます。
だから-a
また奇妙な結果につながります:
$ [ ! -a . ] && echo true
true
-a
3つの引数のコンテキストでは、2項演算子と見なされます。Bash FAQの質問E1を参照してください。POSIXは、それ-a
がKornShellから取得したものであると述べていますが-e
、-a
バイナリと-a
単項を混同するため、後で変更されました。
シェルスクリプトがファイルを開こうとせずにファイルが存在するかどうかを確認する唯一の方法を提供するため、Cシェルによって提供される機能と同様の機能を備えた-eプライマリが追加されました。実装ではファイルタイプを追加できるため、移植可能なスクリプトでは以下を使用できません。
テスト-b foo -o -c foo -o -d foo -o -f foo -o -p foo
fooが既存のファイルかどうかを確認します。歴史的なBSDシステムでは、ファイルの存在は次のように判断できます。
テスト-f foo -o -d foo
しかし、既存のファイルが通常のファイルであると判断する簡単な方法はありませんでした。初期の提案ではKornShell -aプライマリ(同じ意味を持つ)を使用していましたが、-aプライマリと-aバイナリ演算子を混同する可能性が高いという懸念があったため、これを-eに変更しました。
-a
バイナリは、式が曖昧になり、引数が4つ以上になるため、陳腐化のマークも付けられます。これらの4つ以上の引数式では、POSIXは結果が未指定であることを定義します。
.1。では、[-a $ FILE]と[-e $ FILE]の違いは何ですか(ある場合)。
全く違いはありません。
行の505-507
中test.c
のbashのバージョンの4.2.45(1)-release
:
case 'a': /* file exists in the file system? */
case 'e':
return (sh_stat (arg, &stat_buf) == 0);
これは、両方のフラグに実際の違いがないことを示しています。
.2。実際の違いがない場合、同じ目的で2つのフラグが存在するのはなぜですか?
gnoucの回答を参照してください。
-a
がbashのブール演算子(および)でもあることを考えると、完全に冗長であるこの追加の意味を追加するバグが発生しやすいようです。私はそれが他のいくつかの実装との互換性や以前のバージョンとの互換性に関連していたと思います-e
。
-a
し、-o
ブール値のために[ test ]
。しかし、一部のシェル(などbash
)は、引数と演算子を区別するの[ test ]
が難しく、結果は信頼できませんでした。それ以降、POSIXは、準拠するシェルが[ test ]
ブラケット内の少なくとも4つの引数を処理することを要求しています。
私が見つけた最良の答えは、StackOverflowの質問からこれです:
-a
は非推奨であるため、マンページには記載されてい/usr/bin/test
ませんが、bashにはまだ記載されています 。を使用し-e
ます。シングル '['の場合、bashビルトインはandとtest
同じように動作するbashビルトインと同じように動作します (一方は他方へのシンボリックリンクです)。の効果はその位置に依存することに注意してください。最初にある場合は、を意味します。2つの式の中間にある場合は、論理を意味します。/usr/bin/[
/usr/bin/test
-a
file exists
and
[ ! -a /path ] && echo exists
bashのマニュアルで-a
は2項演算子と見なされているため、動作しません。上記はaとしてではnegate -a ..
なく、if '!' and '/path' is true
(空ではない)として解析されます。したがって、スクリプトは常に出力し"-a"
(実際にはファイルをテストします)、"! -a"
実際にはand
ここではバイナリ です。の場合
[[
、-a
はバイナリとして使用されand
なくなった(&&
そこで使用されている)ため、その固有の目的はそこにあるファイルを確認することです(非推奨ですが)。したがって、否定は実際にあなたが期待することを行います。