許可が拒否されたすべてのメッセージを非表示にする必要があります。
find . > files_and_folders
そのようなメッセージが発生したとき、私は実験しています。それが発生しないすべてのフォルダーとファイルを収集する必要があります。
files_and_folders
アクセス許可レベルをファイルに指示することは可能ですか?
エラーを同時に非表示にするにはどうすればよいですか?
許可が拒否されたすべてのメッセージを非表示にする必要があります。
find . > files_and_folders
そのようなメッセージが発生したとき、私は実験しています。それが発生しないすべてのフォルダーとファイルを収集する必要があります。
files_and_folders
アクセス許可レベルをファイルに指示することは可能ですか?
エラーを同時に非表示にするにはどうすればよいですか?
使用する:
find . 2>/dev/null > files_and_folders
これPermission denied
により、もちろんエラーだけでなく、すべてのエラー メッセージが非表示になります。
シンボリックリンクのホップ数が多すぎるなど、他の可能性のあるエラーを本当に保持したいが、許可が拒否されたものは保持したくない場合は、おそらく「許可が拒否された」と呼ばれるファイルが多くないことを推測する必要があります。そして試してください:
find . 2>&1 | grep -v 'Permission denied' > files_and_folders
標準エラーのみを厳密にフィルタリングしたい場合は、より複雑な構造を使用できます。
find . 2>&1 > files_and_folders | grep -v 'Permission denied' >&2
find
コマンドの I/O リダイレクトは次のとおり2>&1 > files_and_folders |
です。パイプは標準出力をgrep
コマンドにリダイレクトし、最初に適用されます。は、2>&1
標準エラーを標準出力と同じ場所 (パイプ) に送信します。は、> files_and_folders
標準出力 (標準エラーではない) をファイルに送信します。最終的な結果として、標準エラーに書き込まれたメッセージはパイプを介して送信され、通常の出力がfind
ファイルに書き込まれます。標準出力をフィルタリングします(grep
どの程度選択するかを決定でき、ロケールとO / Sに応じてスペルを変更する必要がある場合があります)および最終>&2
残りのエラーメッセージ (標準出力に書き込まれる) がもう一度標準エラーに送られることを意味します。最終的なリダイレクトは端末ではオプションと見なすことができますが、標準エラーにエラー メッセージが表示されるようにスクリプトで使用することをお勧めします。
やりたいことに応じて、このテーマには無限のバリエーションがあります。これは、任意の Bourne シェル派生物 (Bash、Korn など) および任意の POSIX 準拠バージョンの Unix のバリアントで動作しますfind
。
システムにあるの特定のバージョンに適応させたい場合はfind
、別のオプションが利用できる場合があります。特にGNUfind
には、他のバージョンでは利用できない無数のオプションがあります。そのようなオプションのセットについては、現在受け入れられている回答を参照してください。
ノート:
find 2>/dev/null
多くの状況で十分である可能性があります. クロスプラットフォームの観点と、可能な限り堅牢なソリューションを見つけるためのいくつかの高度なシェル手法の議論については、まだ興味深いかもしれませんが、保護されているケースはほとんど仮説に基づいている可能性があります.シェルがbash
またはzsh
の場合、POSIX 準拠の機能のみを使用して、適度にシンプルでありながら堅牢なソリューションがあります。それ自体は POSIX の一部ではありませんが、ほとんどの最新の Unix プラットフォームには POSIX が付属しているため、このソリューションは広く移植可能になっています。find
bash
find . > files_and_folders 2> >(grep -v 'Permission denied' >&2)
ノート:
システムがローカライズされたエラー メッセージを表示するように構成されている場合は、find
以下の呼び出しの前にLC_ALL=C
( LC_ALL=C find ...
) を付けて、英語のメッセージが報告されるようにしgrep -v 'Permission denied'
、意図したとおりに機能するようにします。ただし、表示されるエラー メッセージは必ず英語でも表示されます。
>(...)
は、(めったに使用されない)出力 をリダイレクトできる出力プロセス置換です (この場合、 stderr output ( 2>
) は、 内のコマンドの stdin です>(...)
。およびに
加えて、原則としてそれらもサポートしますが、それらを からのリダイレクトと組み合わせようとしています。ここ ( ) で行われているstderrは、黙って無視されているように見えます( )。bash
zsh
ksh
2> >(...)
ksh 93u+
grep -v 'Permission denied'
句を含むすべての行を (コマンドの stderr ストリームから) 除外し ( ) 、残りの行を stderr に出力します ( )。-v
find
Permission denied
>&2
注: の出力の一部が完了後にgrep
到着する可能性がわずかにあります。これは、コマンド全体が内部のコマンドの終了を待たないためです。では、コマンドに追加することでこれを防ぐことができます。 find
>(...)
bash
| cat
このアプローチは次のとおりです。
Robust :エラー メッセージgrep
にのみ適用され(ファイル パスとエラー メッセージの組み合わせには適用されず、誤検知につながる可能性があります)、アクセス許可が拒否されたもの以外のエラー メッセージは stderr に渡されます。
side-effect free :find
の終了コードは保持されます: 遭遇したファイルシステム項目の少なくとも 1 つにアクセスできないと、終了コードが返されます(ただし、アクセス拒否以外の1
エラーが発生したかどうかはわかりません)。
完全に POSIX に準拠したソリューションには、制限があるか、追加の作業が必要です。
の出力をとにかくファイルfind
にキャプチャする(または完全に抑制する) 場合、 Jonathan Leffler の回答からのパイプラインベースのソリューションは、シンプルで堅牢で、POSIX に準拠しています。
find . 2>&1 >files_and_folders | grep -v 'Permission denied' >&2
リダイレクトの順序が重要であることに注意してください:最初2>&1
に来る必要があります。
stdout 出力を事前にファイルにキャプチャすると、パイプラインを介してエラー メッセージのみ2>&1
を送信でき、エラー メッセージは明確に操作できます。grep
唯一の欠点は、全体的な終了コードgrep
がではなくコマンドのになることfind
です。これは、この場合、エラーがまったくない場合、または許可が拒否されたエラーのみ1
の場合、終了コードは(signaling failure ) になり、そうでない場合は (権限が拒否されたもの以外のエラー) 0
- これは意図の反対です。
とはいえ、find
の終了コードは、存在しないパスを渡すなどの基本的な障害以外の情報をほとんど伝達しないことが多いため、いずれにしてもめったに使用されません。
ただし、一部のみの特定のケースでもパーミッションがないためにアクセスできない入力パスの数は、の終了コードに反映されfind
ます (GNU と BSD の両方):処理されたファイルのいずれかfind
でパーミッション拒否エラーが発生した場合、終了コードは に設定されます。1
次のバリエーションは、次のことに対処します。
find . 2>&1 >files_and_folders | { grep -v 'Permission denied' >&2; [ $? -eq 1 ]; }
現在、終了コードは、発生した以外の Permission denied
エラーが発生したかどうか1
を示し0
ます。
つまり、終了コードはコマンドの真の意図を反映するようになりました。エラーが0
まったくない場合、または許可拒否エラーのみが発生した場合、成功 ( ) が報告されます。これは、上部のソリューションのように、 の終了コードを
単に渡すよりも間違いなく優れています。find
コメントのgniourf_gniourfは、洗練されたリダイレクトを使用して、このソリューションの (まだ POSIX 準拠の)一般化を提案しています。これは、ファイル パスをstdoutに出力するデフォルトの動作でも機能します。
{ find . 3>&2 2>&1 1>&3 | grep -v 'Permission denied' >&3; } 3>&2 2>&1
つまり、カスタム ファイル記述子を使用して stdout ( ) と stderr ( )3
を一時的に交換し、エラー メッセージだけを stdout 経由でパイプすることができます。1
2
grep
これらのリダイレクトがないと、データ (ファイル パス)とgrep
エラー メッセージの両方がstdout 経由でパイプされgrep
、エラー メッセージ Permission denied
と、名前にPermission denied
.
ただし、最初の解決策と同様に、報告される終了コードはgrep
ではなくfind
になりますが、上記と同じ修正を適用できます。
Michael Brux の回答については、find . ! -readable -prune -o -print
次の点に注意する必要があります。
GNU が必要find
です。特に、macOS では動作しません。もちろん、 GNU で動作するコマンドだけが必要な場合はfind
、これは問題になりません。
一部のPermission denied
エラーは引き続き発生する可能性があります:現在のユーザーがアクセス許可を持っているが、 (実行可能) アクセス許可を欠いているディレクトリの子項目find ! -readable -prune
について、このようなエラーを報告します。その理由は、ディレクトリ自体は読み取り可能であり、実行されず、そのディレクトリに降りようとするとエラーメッセージがトリガーされるためです。とはいえ、典型的なケースは許可が欠落している場合です。r
x
-prune
r
注: 次の点は、哲学および/または特定の使用例の問題であり、特にパスを印刷するだけで十分である場合は、それが自分には関係なく、コマンドがニーズに適していると判断する場合があります。
find
find
-name
find . ! -readable -prune -o -name '*.txt'
-print
Jonathan Leffler の回答の最初の解決策はfind . 2>/dev/null > files_and_folders
、彼自身が述べているように、 すべてのエラー メッセージをやみくもに黙らせます(彼も説明しているように、回避策は面倒で、完全には堅牢ではありません)。ただし、実用的に言えば、これが最も簡単な解決策です。すべてのエラーが権限に関連していると想定して満足しているかもしれません。
ミストの答えは簡潔sudo find . > files_and_folders
で実用的ですが、セキュリティ上の理由から、単にファイル名を印刷する以外にはお勧めできません: rootユーザーとして実行しているため、「find のバグによってシステム全体が台無しになるリスクがあります。または悪意のあるバージョン、または予想外に何かを書き込む誤った呼び出し。通常の権限でこれを実行した場合は発生しませんでした」(トリプルによるミストの回答に関するコメントから)。
viraptor's answerの2 番目のソリューションは、find . 2>&1 | grep -v 'Permission denied' > some_file
(パイプラインを介して stdout と stderr の混合を送信するため) 誤検知のリスクを冒し、潜在的に、stderr を介して非許可拒否エラーを報告する代わりに、出力パスと一緒にそれらをキャプチャします。出力ファイルで。
ルート "/" から検索を開始する場合、おそらく次のような出力が表示されます。
find: /./proc/1731/fdinfo: Permission denied
find: /./proc/2032/task/2032/fd: Permission denied
許可だからです。これを解決するには:
sudo コマンドを使用できます。
sudo find /. -name 'toBeSearched.file'
スーパーユーザーのパスワードを尋ねます。パスワードを入力すると、本当に必要な結果が表示されます。sudo コマンドを使用する権限がない場合、つまりスーパー ユーザーのパスワードを持っていない場合は、まずシステム管理者に依頼して sudoers ファイルに追加してもらいます。
標準エラー出力を(通常はディスプレイ/画面)からいくつかのファイルにリダイレクトして、画面にエラーメッセージが表示されないようにすることができます。特別なファイル /dev/null にリダイレクトします:
find /. -name 'toBeSearched.file' 2>/dev/null
標準エラー出力を (通常はディスプレイ/画面) から標準出力 (通常はディスプレイ/画面) にリダイレクトしてから、grep コマンドで -v "invert" パラメータを指定してパイプし、「許可が拒否されました」という出力行が表示されないようにすることができます。単語のペア:
find /. -name 'toBeSearched.file' 2>&1 | grep -v 'Permission denied'
私は使用しなければなりませんでした:
find / -name expect 2>/dev/null
見つけたいものの名前を指定し、すべてのエラーを /dev/null にリダイレクトするように指示します
私が探していたexpectプログラムの場所であることを期待してください。
2> / dev/nullを使用してパイプstderr
します/dev/null
find . -name '...' 2>/dev/null
-perm
また、述語と述語を使用して、-prune
読み取り不能なディレクトリに降りないようにすることもできます ( 「検索プログラムから "許可が拒否された" 出力ステートメントを削除するにはどうすればよいですか? - Unix & Linux Stack Exchangeも参照してください):
find . -type d ! -perm -g+r,u+r,o+r -prune -o -print > files_and_folders
標準エラーをリダイレクトします。たとえば、UNIX マシンで bash を使用している場合、次のように標準エラーを /dev/null にリダイレクトできます。
find . 2>/dev/null >files_and_folders
これらのエラーは、標準エラー出力(fd 2)に出力されます。それらを除外するには、すべてのエラーを/ dev/nullにリダイレクトするだけです。
find . 2>/dev/null > some_file
または、最初にstderrとstdoutを結合してから、これらの特定のエラーをgrepします。
find . 2>&1 | grep -v 'Permission denied' > some_file
find . > files_and_folders 2>&-
2>&-
-
標準エラー ファイル記述子 ( ) を閉じる ( 2
) ため、すべてのエラー メッセージが表示されなくなります。
1
' Permission denied
' エラーが表示されない場合でも、終了コードはそのままです。find
:find . -type d \! \( -readable -executable \) -prune -print -o -print > files_and_folders
それに追加のオプションを渡します(下に降りることを防ぎます) が、find
( ) 権限と権限の両方を持たない ( )ディレクトリ ( )または ( )他のファイル。-prune
-print
-type
d
\!
-readable
-executable
-o
-print
-readable
-executable
オプションはGNU拡張であり、POSIX標準の一部ではありませんPermission denied
異常/破損したファイルで「 」を返す場合があります (たとえば、 v2.0.5 未満を使用しているコンテナーにマウントされたファイルシステムに影響を与えるバグ レポートを参照してください)。lxcfs
find
(GNU、OSX/BSDなど)で動作する堅牢な回答{ LC_ALL=C find . 3>&2 2>&1 1>&3 > files_and_folders | grep -v 'Permission denied'; [ $? = 1 ]; } 3>&2 2>&1
パイプラインを使用して標準エラー ストリームを に渡し、文字列grep
を含むすべての行を削除し'Permission denied'
ます。
LC_ALL=C
環境変数を使用してPOSIX ロケールを設定し、ファイル記述子を複製して標準エラー ストリームを にパイプし、によって返されたエラー コードを反転しての元の動作に近づけます。3>&2 2>&1 1>&3
3>&2 2>&1
grep
[ $? = 1 ]
[]
grep
find
'Permission denied'
します (たとえば、files_and_folders
ファイル自体が書き込み可能でない場合) 。アクセス許可が拒否されたという警告だけを回避するには、読み取り不能なファイルを検索から除外して無視するように find に指示します。次のように、式を検索結果に OR として追加します。
find / \! -readable -prune -o -name '*.jbd' -ls
これは主に(読み取り不可能なファイルに一致し、リストから削除する)または( *.jbdのような名前に一致し、それを [ls で] 表示する) と言います。(デフォルトでは、-or を使用しない限り、式は AND で結合されることに注意してください。) 2 番目の式に -ls が必要です。そうしないと、find がいずれかの一致を表示するデフォルト アクションを追加することができます。これにより、すべての読み取り不能ファイルも表示されます。 .
しかし、システム上の実際のファイルを探している場合、多くのファイルがある /dev を調べる理由は通常ありません。そのため、次のように、そのディレクトリを除外する式を追加する必要があります。
find / -mount \! -readable -prune -o -path /dev -prune -o -name '*.jbd' -ls
したがって、(読み取り不可能なファイルに一致し、リストからプルーニングする)または(パス /dev に一致し、リストからプルーニングする)または( *.jbdのようなファイルに一致し、それを表示する)。
使用する
sudo find / -name file.txt
それはばかげており (検索を昇格させるため)、安全ではありませんが、書くのははるかに短くなります。
上記の答えはどれもうまくいきませんでした。私がインターネットで見つけたものはすべて、エラーを隠すことに焦点を当てています。プロセスの return-code / exit-code を適切に処理するものはありません。私は bash スクリプト内でコマンド find を使用して、いくつかのディレクトリを見つけ、その内容を調べます。終了コードを使用して、コマンド検索の成功を評価します。値がゼロの場合は機能し、それ以外の場合は失敗します。
上記のMichael Bruxによる回答が機能する場合があります。しかし、失敗するシナリオが 1 つあります。問題を発見し、自分で修正しました。次の場合にファイルを整理する必要があります。
it is a directory AND has no read access AND/OR has no execute access
ここでの重要な問題は、AND/OR です。私が読んだ良い推奨条件シーケンスは次のとおりです。
-type d ! -readable ! -executable -prune
これは常に機能するとは限りません。これは、一致が次の場合にプルーニングがトリガーされることを意味します。
it is directory AND no read access AND no execute access
読み取りアクセスは許可されているが、実行アクセスは許可されていない場合、この一連の式は失敗します。
いくつかのテストの後、私はそれを認識し、シェル スクリプト ソリューションを次のように変更しました。
nice find /home*/ -maxdepth 5 -follow \
\( -type d -a ! \( -readable -a -executable \) \) -prune \
-o \
\( -type d -a -readable -a -実行可能 -a -name "${m_find_name}" \) -print
ここで重要なのは、結合された式に「正しくない」を配置することです。
has read access AND has execute access
それ以外の場合は、完全なアクセス権がありません。つまり、プルーニングします。これは、以前に提案された解決策が失敗した1つのシナリオでうまくいくことが証明されました。
コメント セクションの質問については、以下の技術的な詳細を提供します。詳細が過度である場合は申し訳ありません。
最小限の解決策は、readable
フラグを追加することです。
find . -name foo -readable