%20%E3%81%AF%E7%B5%90%E6%9E%9C%E3%82%92%E5%A4%89%E6%9B%B4%E3%81%97%E3%81%BE%E3%81%9B%E3%82%93%E3%81%8C%E3%80%81for%20-e%20%E3%81%AF%E5%A4%89%E6%9B%B4%E3%81%97%E3%81%BE%E3%81%99%E3%80%82.png)
混乱していますが、まだBashを誤解しているようです。
/$ if [ -e /bin/grep ]; then echo yea; else echo nay ; fi
yea
/$ if [ ! -e /bin/grep ]; then echo yea; else echo nay ; fi
nay
/$ if [ -a /bin/grep ]; then echo yea; else echo nay ; fi
yea
/$ if [ ! -a /bin/grep ]; then echo yea; else echo nay ; fi
yea
否定はなぜ!
テストの効果を反転させますが、テストの効果は反転しませ-e
んか?-a
マン・バッシュはこう言いました。
テスト:
3つのパラメータ
次の条件は、リストされた順序で適用されます。
- 2 番目の引数が上記の条件式にリストされた 2 進条件付き演算子の 1 つである場合、式の結果は、1 番目と 3 番目の引数をオペランドとして使用するバイナリ テストの結果です。引数が3つの場合、
-a
and演算子は二項演算子として扱われます。-o
- 最初の引数がある場合、値
!
は2番目と3番目の引数を使用する2つのパラメータテストの否定です。
Bash条件式
[[
条件式は、複合コマンドと組み込みtest
コマンド[
で使用されます。
-a file
ファイルが存在する場合は真です。
-b file
ファイルが存在し、ブロック特殊ファイルの場合は真です。
-c file
ファイルが存在し、文字特殊ファイルの場合はTrue。
-d file
ファイルが存在し、ディレクトリであれば真です。
-e file
ファイルが存在する場合は真です。
答え1
-a
単項演算子(a
アクセシビリティのためにKornシェルとの互換性のために追加されましたが、それ以外の場合は非標準で現在重複しています-e
)と二項演算子(a
POSIXでは(XSIを使用)ndの場合は廃止予定です)演算子です。
ここに[ ! -a /bin/grep ]
電話するバイナリPOSIX に必要な演算子です。空でないことを[ "$a" -a "$b" ]
テストすることです。$a
そして $b
$a
空ではありません。ここに==!
と$b
==があります/bin/grep
。どちらの文字列も空ではないので、返します本物。
また見てください「3つの引数がある場合、-aおよび-o演算子は二項演算子として扱われます。」あなたが引用した本文です。
-a
単項形式とバイナリ形式の両方が廃止され、単項形式が置き換えられるため、バイナリ形式は-e
信頼できず、あいまいなテスト式を生成するため、使用されなくなりました。
ファイルが存在するかどうかをテストします。 (実際にはファイルが存在するかどうかをテストする方が重要です。)アクセシビリティ、stat()
パスで成功しますか? 1)、. [ -e filepath ]
toを使用してください。そして&&
通貨間で使用される2つの条件[
。
文字列が空でないことをテストするには、個人的に型[ -n "$string" ]
よりも[ "$string" ]
型を好みます。
だから:
ファイルが存在するかどうかをテストします。
[ -e "$file" ] # not [ -a "$file" ] [ ! -e "$file" ] # not [ ! -a "$file" ]
両方の文字列が空でないことをテストします。
[ -n "$a" ] && [ -n "$b" ] # not [ "$a" -a "$b" ] [ "$a" ] && [ "$b" ]
~からPOSIX仕様のユーティリティの基本test
(別名)[
:
-a および -o デフォルトのバイナリと「(」および「)」演算子を指定する XSI 拡張は、廃止とマークされています。 (これを使用する多くの式は、評価される特定の式に従って構文によってあいまいに定義されます。)これらの式を使用するスクリプトは、以下の形式に変換する必要があります。多くの実装はこれらの古い形式を引き続きサポートしていますが、スクリプトはユーザー提供の入力を処理するときに非常に注意する必要があります。これは、これらの基本型や演算子と混同される可能性があるためです。
そして:
最初の提案では、KornShell -a基本演算子(同じ意味を持つ)を使用しましたが、人々が-a基本演算子と-aバイナリ演算子を混同する可能性があるため、後で-eに変更しました。
yash
、、bosh
GNUマニュアルはcoreutils
各実装でバイナリ/の使用を防ぎ、-a
マニュアルはこれを文書化しません²。しかし、残念ながら(GNUシェル)を含む他の多くのマニュアルはまだバイナリ/の使用を禁止しません。-o
[
test
zsh
bash
1 詳細については、以下を参照してください。これは、関連するstackoverflow Q&Aに対する私の答えです。
²a test
/[
組み込み機能は、1991年バージョン2.0.3でのみzshに追加されました。[[ ... ]]
Kornシェルの特別な構成は常に優先され、次の目的で&&
使用||
される独自の構文を持ちます。そしてそしてまたはオペレーター。
答え2
Bashは、空でなければtrueと評価される2つの単一単語テストで囲まれた「and」を意味する2項演算子[ ! -a WORD ]
で解析します。-a
したがって[ ! -a "" ]
、falseまたはnullでない場合はtrueです[ ! -a WORD ]
。WORD
この分析は以下と一致する。POSIX仕様(厳密には、POSIXは単項を指定しないため、これを行う必要はありません-a
。)BTW、mksh、およびzshはこの場合を同じ方法で解析しますが、ksh93は単項を使用して!
解析します-a
。
あいまいさを避けるために、廃止された演算子を使用しないで、二項演算子とスペルが等しくない-a
標準演算子を使用してください。-e
また、長い特別なケースであいまいさやエラーを防ぐために、潜在的にあいまいな/ insideの代わりにバイナリ演算子(externalまたはInternal)としておよびを&&
使用してください。||
[ … ]
[[ … ]]
-a
-o
[ … ]