web-dev-qa-db-ja.com

Bashファイルの存在テストは常にtrueです

ファイルが存在するかどうかをテストするbashスクリプトの次の行があります。

MYAPPPATH=$(find $APPDIR -iname myapp* -print)
if [ -e $MYAPPPATH ]
then
    echo "File exists" 
fi

ただし、「myapp」で始まるファイルが存在しないため、MYAPPPATH = ''の場合、上記のチェックは再び成功します。 set -xを使用し、ファイルが存在しない場合にどうなるかを確認します。

++ find /path/to/app -iname 'myapp*' -print
+ MYAPPPATH=
+ '[' -e ']'
+ echo 'File exists'

これの理由は何ですか?

これを期待どおりに機能させるには、何をする必要がありますか?

5
trikelef

変数が空の場合、コマンドは次のようになります。

[ -e ]

この場合、1つの引数[..]を指定して-eを呼び出します。文字列"-e"はnullではないため、testはtrueを返します。

この動作は次のように定義されます POSIXテスト

次のリストでは、$ 1、$ 2、$ 3、および$ 4は、テストのために提示された引数を表します。

0引数:

Falseを終了します(1)。

1つの引数:

$ 1がnullでない場合は、true(0)を終了します。それ以外の場合は、falseを終了します。

....

それを機能させるには、 変数を二重引用符で囲む

[ -e "$MYAPPPATH" ]

空の文字列である引数を持つ-eがfalseであるため、これは機能します。

13
cuonglm

変数の引用に慣れてください。常に引用してください。必要なときに誤評価を防ぎます。

if [ -e "$MYAPPPATH" ]

これは、bash固有の複合コマンドでは発生しませんでした。

if [[ -e $MYAPPPATH ]]
5
Hauke Laging

他にもいくつかの方法があります。

  1. 前に変数を確認してください(コメントによるエディションで)

    if [ -n "$MYAPPPATH" ] && [ -e "$MYAPPPATH" ] ; then ...
    
  2. locateの代わりにfind *を使用してください

    if locate -w "$APPDIR/myapp*" ; then ...
    

* 1 locateを使用するには、updatedbでファイルデータベースを更新することを忘れないでください

2
Costas