一致するファイルが見つからない場合、 `find`が0以外を返すようにできますか?


46

/tmp呼び出されるファイルがない場合でもsomething、で検索するとfind0が返されます。

  $ find /tmp -name something 
  $ echo $?
  0

find何も見つからない場合、ゼロ以外の終了ステータスを取得するにはどうすればよいですか?

回答:


44

ここにあなたが望むものを行うと思うワンライナーがあります:

find /tmp -name something | egrep '.*'

戻りステータスは0、何かが見つかった場合になり、そうでない場合はゼロ以外になります。

findさらに処理するためにの出力もキャプチャする必要がある場合は、Svenの答えがそれをカバーしています。


14
トレーリング*上のegrep正規表現は、完全に冗長です。egrep正規表現の構文を使用していないため、単純な旧式の方grepが数マイクロ秒高速になる場合があります。
トリプリー

私は使用することを学びましたfind ... | read
サム

14

印刷せず、結果が見つかったときに0で終了する最も簡単なソリューション

find /tmp -name something | grep -q "."

2
ここでは二重引用符は意味を持ちません。
haridsv

二重引用符はコード機能を提供しませんが、ピリオド文字がディレクトリではなく正規表現であることを読者に明確にします。
ダルマベラムコンダ

13

終了0は検索で簡単ですが、終了> 0はより困難です。これは通常、エラーが発生した場合にのみ発生するためです。ただし、それを実現することはできます。

if find -type f -exec false {} +
then
  echo 'nothing found'
else
  echo 'something found'
fi

2
私が知る限り、これは機能しません。の終了コードはfind、実行した-execsの終了コードに依存していないようです。
クリス

@クリスは私のために働いており、賛成した4人
スティーブンペニー

このソリューションの誤った誤った結果の例: find / existing-starting-point / non-existing-starting-point -name file-in-existing-starting-point -exec false {} +
Gerald Schade

2
これは正しく機能し、文書化されています(ただしexec、戻り値の下ではなく、セクションに隠されています)。見つからないものを区別することはできず、エラーが発生することもあります(存在しない開始点で呼び出された場合など)。
Tgr

この機能が必要な場合-はい
ジェラルドシェード

7

Puppetの問題を解決する私の方法を見つけようとしているときにこの質問を見つけただけです(ディレクトリ自体ではなくディレクトリの下のフォルダのアクセス許可を変更します)、これはうまくいくようです:

! test -z $(find /tmp -name something)

私の特定のユースケースはこれです:

! test -z $(find /home -mindepth 1 -maxdepth 1 -perm -711)

findコマンドが必要な権限を持つファイルを見つけられない場合、コード1を終了します。


ここでは、いくつかの解決策(すべて試していない)がMacで機能しませんでした。これでした。
アレックスホール

5

不可能です。Findは、ファイルが見つからなかった場合でも、正常に終了した場合は0を返します(ファイルが実際に存在しない場合はエラーを示さない正しい結果です)。

検索マンページを引用するには

終了ステータス

すべてのファイルが正常に処理された場合はステータス0、エラーが発生した場合は0より大きい終了を検索します。これは意図的に非常に広範な説明ですが、戻り値がゼロ以外の場合、findの結果の正確さに依存するべきではありません。

達成したい内容に応じて-print、ファイル名を見つけて、その出力に対してテストすることができます。

#!/bin/bash
MYVAR=`find . -name "something" -print`
if [ -z "$MYVAR" ]; then
    echo "Notfound"
else
   echo $MYVAR
fi

確かに可能ですが、必要なほど堅牢ではありません。
ルスラン

マニュアルページの構成が不十分です。ルスランが言ったことは、exec/ execdirオプションの下に文書化されています(で使用+):If any invocation returns a non-zero value as exit status, then find returns a non-zero exit status.
Tgr

1

これが最も簡潔で直接的な方法だと思います。

test `find /tmp/ -name something -print -quit 2>/dev/null`

2
この場合、findでエラーが発生すると、結果が/ dev / nullに出力され、ゼロ以外の終了が返され、テストコマンドで0に固定されます。
ジェフファーランド

私はそれが本当だとは思わない。あなたの例を説明してください。エラーが発生して出口を見つけると、文字列は空になり、テストはゼロ以外を返します。
ダノートン

あなたの例が何であるかはわかりませんが、-print -quitあなたの懸念に対処するかもしれない誤って省略しました。
-danorton

おそらく、(おそらく同じ理由で)ダウン投票した他の人が反対の例を提供できるでしょうか?
-danorton

1
さて、あなたは私のスタイルが好きではありません。私のユースケースでは、検出されるエラーはノイズであるか、他の場所に表示されるほど深刻なものです。いずれの場合でも、このメソッドは最終的な質問に正しく答えます。「指定された名前のパスにアクセス可能なファイルがあります。」エラーは、「いいえ」の正しい答えを返します。なぜそうなのかを知りたい場合は、元々ここに提示されていない質問に答えるより複雑なコードを追加できます。
-danorton

0

ここに私が呼んだ小さなスクリプトがありますtest.py。設定されている場合はエラーコードを返し、findがファイルを一覧表示しなかった場合はさらにエラーコードを返すという点で投稿された他のメソッドを改善します。

from subprocess import Popen
import sys

p = Popen(['find'] + sys.argv)
out, err = p.communicate()
if p.returncode:
    sys.exit(p.returncode)
if not out:
    sys.exit(1)

コマンドライン出力は次のとおりです。

$ python test.py . -maxdepth 1 -name notthere
$ echo $?
1
$ find . -maxdepth 1 -name notthere
$ echo $?
0
$ find . -failedarg
find: unknown predicate `-failedarg'
$ echo $?
1

次に、findでエラーが発生したがファイルが見つかった結果について:

$ ls -lh
$ d---------  2 jeff users   6 Feb  6 11:49 noentry
$ find .
.
./noentry
find: `./noentry': Permission denied
$ echo $?
1
$ find . | egrep '.*'
.
./noentry
find: `./noentry': Permission denied
$ echo $?
0
python ../test.py 
../test.py
$ echo $?
1

次に、ファイルのリストが必要な場合は、-print 0渡されfindた変数を使用して、nullでout変数を分割するか、単にprintステートメントを追加します。


-1

find成功したときに終了ステータスコードをゼロとして返すだけではありません。UNIXでは、実行するコマンドが何であれ、成功すると終了ステータスをゼロとして返します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.