Bashファイル存在テストは常に真です。

Bashファイル存在テストは常に真です。

ファイルが存在するかどうかをテストするために、次の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'

その理由は何ですか?

このタスクが期待どおりに機能するにはどうすればよいですか?

答え1

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

[ -e ]

この場合、[..]1つのパラメータで呼び出すことができます-e。文字列"-e"はnullではないため、testtrueが返されます。

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

次のリストでは、$ 1、$ 2、$ 3、および$ 4はテストするパラメータを示しています。

パラメータ0:

偽(1)を終了します。

パラメータ1つ:

$1 が null でない場合は true(0) を返し、そうでない場合は false を返します。

....

動作するには、次の操作を行う必要があります。変数を二重引用符で囲む:

[ -e "$MYAPPPATH" ]

-eこれは、パラメータが空の文字列の場合はfalseであるために機能します。

答え2

変数の引用に慣れてください。常に引用してください。これにより、必要に応じて誤った評価を防ぐことができます。

if [ -e "$MYAPPPATH" ]

bash関連の複合コマンドを使用すると、これは発生しません。

if [[ -e $MYAPPPATH ]]

答え3

他の方法もあります:

  1. 以前に変数を確認してください(説明に従ってバージョンを使用)。

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

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

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

関連情報