許可を拒否されたメッセージをすべて非表示にする必要があります。
find . > files_and_folders
私はそのようなメッセージが出たときに実験しています。それが発生しないすべてのフォルダーとファイルを収集する必要があります。
アクセス許可レベルをfiles_and_folders
ファイルに送ることは可能ですか?
どうすれば同時にエラーを非表示にできますか?
許可を拒否されたメッセージをすべて非表示にする必要があります。
find . > files_and_folders
私はそのようなメッセージが出たときに実験しています。それが発生しないすべてのフォルダーとファイルを収集する必要があります。
アクセス許可レベルをfiles_and_folders
ファイルに送ることは可能ですか?
どうすれば同時にエラーを非表示にできますか?
回答:
注:
*この答えは、おそらくユースケースの保証よりも深くfind 2>/dev/null
、多くの状況で十分な場合があります。それは、クロスプラットフォームの観点から、また、ガードされたケースが大部分は仮説であるとしても、可能な限り堅牢なソリューションを見つけるためのいくつかの高度なシェルテクニックの議論にとって興味深いかもしれません。
* ローカライズされたエラーメッセージを表示するようにシステムが構成されている場合は、find
以下の呼び出しの前にLC_ALL=C
(LC_ALL=C find ...
)を付けて、英語のメッセージが報告さgrep -v 'Permission denied'
れるようにしてください。常に、しかし、すべてのエラーメッセージか表示されますが、その後にも英語になります。
あなたの場合はシェルがあるbash
かzsh
、があります合理的にシンプルでありながら堅牢なソリューション使用して、唯一のPOSIX準拠のfind
機能は、一方、bash
POSIXの一部ではない、それ自体、最も近代的なUnixプラットフォームでは、このソリューションが広くポータブル作り、それが付属しています:
find . > files_and_folders 2> >(grep -v 'Permission denied' >&2)
注:コマンド全体が内部のコマンドの終了を待機しないため、完了後に一部grep
のの出力が到着する可能性が少しあります。では、コマンドに追加することでこれを防ぐことができます。 find
>(...)
bash
| cat
>(...)
(まれに使用される)出力 プロセスの置換で、出力(この場合はstderr出力(2>
)を内部のコマンドのstdinにリダイレクトできます>(...)
。およびに
加えて、原則としてそれらもサポートしていますが、からのリダイレクトと組み合わせようとしていますここで行われているように()、stderrは黙って無視されているように見えます(内)。bash
zsh
ksh
2> >(...)
ksh 93u+
grep -v 'Permission denied'
フィルタリングアウト(-v
)(からのすべての行find
のフレーズが含まれているコマンドの標準エラー出力ストリーム)Permission denied
とstderrに残りの行を出力します(>&2
)。このアプローチは次のとおりです。
ロバスト:エラーメッセージにgrep
のみ適用され(ファイルパスとエラーメッセージの組み合わせには適用されず、誤検出につながる可能性があります)、権限が拒否されたメッセージ以外のエラーメッセージはstderrに渡されます。
副作用なし:find
の終了コードは保持されます。検出されたファイルシステムアイテムの少なくとも1つにアクセスできないと、終了コードが生成されます1
(ただし、アクセス許可が拒否されたエラー以外のエラーが発生したかどうかはわかりません)。
完全にPOSIX準拠のソリューションには制限があるか、追加の作業が必要です。
場合はfind
出力がで捕獲されるのファイルとにかく(または完全に抑制さ)、そしてからのパイプラインベースのソリューションジョナサン・レフラーの答えは、単純で堅牢、およびPOSIX準拠であります:
find . 2>&1 >files_and_folders | grep -v 'Permission denied' >&2
リダイレクトの順序が重要であることに注意してください:最初に2>&1
来る必要があります。
stdout出力をファイル内で事前にキャプチャすると、パイプラインを介してエラーメッセージのみ2>&1
を送信でき、パイプラインは明確に操作できます。grep
唯一の欠点ことです全体の終了コードがなりますgrep
コマンドのではなく、find
存在しない場合:この場合の手段での、何の全部またはでエラーのみ許可拒否エラーは、終了コードがします1
(シグナリング失敗を(そうでない場合、)許可が拒否されたエラー以外のエラー)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準拠)を提案する洗練されたリダイレクトを使用して、このソリューションの一般化、さえにファイルパスを印刷するデフォルトの動作で動作する標準出力を:
{ find . 3>&2 2>&1 1>&3 | grep -v 'Permission denied' >&3; } 3>&2 2>&1
つまり、カスタムファイル記述子3
を使用してstdout(1
)とstderr(2
)を一時的にスワップし、エラーメッセージだけgrep
をstdout経由でパイプすることができます。
これらのリダイレクトすることなく、データ(ファイルパス)の両方とエラーメッセージがにパイプされるgrep
STDOUTを介して、及びgrep
次いで区別することができないエラーメッセージ Permission denied
と(仮想)名前が含まれてしまったファイルフレーズPermission denied
。
ただし、最初のソリューションと同様に、報告される終了コードはgrep
のではなくfind
であるが、上記と同じ修正を適用できる。
注意すべきいくつかのポイントがありますマイケル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
アクションがされる必要(説明はこの回答にあります)。このような微妙な問題により、バグが発生する可能性があります。で最初のソリューションジョナサン・レフラーの答えは、find . 2>/dev/null > files_and_folders
彼自身が述べて、 盲目的に沈黙すべてのエラーメッセージを(そして彼はまた説明しているようにこの問題を回避するには、十分に堅牢で面倒ではありません)。実用的に言えば、しかし、それが最も簡単な解決策は、任意およびすべてのエラーは許可関連のだろうと仮定するコンテンツかもしれとして、。
霧の答えは、sudo find . > files_and_folders
、簡潔かつ実用的ではなく、単に以外で無分別で印刷するファイル名をセキュリティ上の理由から、:あなたのように実行しているので、ルートユーザー、「あなたは、findのバグによって台無しにされているあなたの全体のシステムを持つリスクまたは悪意のあるバージョン、または予期せず何かを書き込む不正な呼び出し。これは通常の権限でこれを実行した場合には発生しませんでした。
viraptorの回答の2番目の解決策は、find . 2>&1 | grep -v 'Permission denied' > some_file
(パイプラインを介してstdoutとstderrの混合を送信するために)誤検知のリスクを実行し、場合によっては、stderrを介して非許可拒否エラーを報告する代わりに、出力パスとともにそれらをキャプチャします出力ファイル内。
{ find . 3>&2 2>&1 1>&3 | grep -v 'Permission denied' >&3; } 3>&2 2>&1
>(...)
はBash固有です。
find
強調して宣伝する必要があるかどうかはわかりませんfind
。の終了コードは悪用されていることで有名です。ここでは、それはゼロ以外になる可能性が非常に高くなります(そして無駄にそうなります)。
execute/search
ディレクトリを「検索」(含まれているファイルのiノードを取得)するために、ファイルモード権限を明示的に必要とします。find
(ディレクトリ内read
のファイルをリストする許可を要求することに加えて)サブディレクトリに降りるためにこれを行います。これは「バグ」や「移植エラー」ではありません。
使用する:
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など)を備えたUnixのすべてのバリアント、およびのPOSIX準拠バージョンで動作しfind
ます。
find
システム上にある特定のバージョンに適応したい場合は、代替オプションが利用できる場合があります。find
特にGNU には、他のバージョンでは利用できない無数のオプションがあります。そのようなオプションのセットについては、現在受け入れられている回答を参照してください。
2>/dev/null
、スペースなし!
2>
スペースなしで単一のユニットです。それとファイル名の間にスペースを入れることができます。2>&1
(標準エラーを標準出力が送信されるのと同じ場所にリダイレクトする)など、他のリダイレクトと同様に、または2>&-
標準エラーを閉じます。残りの詳細については、リダイレクトを参照してください。(上記のコードは、POSIXに似た一般的なシェルであり、に固有ではありませんbash
。)
使用する:
find . ! -readable -prune -o -print
より一般的に
find <paths> ! -readable -prune -o <other conditions like -name> -print
動作:find(GNU findutils)4.4.2。バックグラウンド:
-readable
テストは、読み込み可能なファイルにマッチします。!
テストがfalseの場合、オペレータは、trueを返します。また! -readable
、読み取り不可能なディレクトリ(&files)に一致します。-prune
アクションはディレクトリに降りていません。! -readable -prune
翻訳可能:ディレクトリが読み取り可能でない場合は、そのディレクトリに移動しないでください。-readable
テストでは、アカウントのアクセス制御リストやその他の権限の工芸品にかかる-perm
テストは無視します。詳細については、find
(1)のマンページも参照してください。
-o
:find . ! -readable -prune -o -name '*.txt'
find
は-readable
オプションが含まれていないことに注意してください。どちらも行わずfind
BSDので、マックOS X用(私は他のシステムについてはよく分かりません)。したがって、GNUがfind
保証されている場合、これはうまく機能しますが、システムにGNUがfind
インストールされていることを保証できない場合、これをどのように適応するかは明らかではありません。(Linuxでは問題なく動作しますが、他の場所では動作する場合と動作しない場合があります。)
find . ! -readable -prune -o -name '*.txt'
find 4.2.2を使用してUbuntu 14.04で動作しないようです。単調になりそう-name
です。いくつかの奇妙な理由で、私は成功しましたfind . \( ! -readable -prune \) -o -name '*.txt' -print
ルート "/"から検索を開始する場合、おそらく次のような出力が表示されます。
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'
sudo find...
私は使用しなければなりませんでした:
find / -name expect 2>/dev/null
検索したいものの名前を指定して、すべてのエラーを/ dev / nullにリダイレクトするように指示する
私が探していた期待プログラムの場所であることを期待しています。
expect
。代わりに、expect
このコマンドが検索しようとするファイルの名前です。
-perm
および-prune
述語を使用して、読み取り不可能なディレクトリへの下降を回避することもできます(「許可が拒否された」印刷出力ステートメントをfindプログラムから削除するにはどうすればよいですか?-Unix&Linux Stack Exchangeも参照してください)。
find . -type d ! -perm -g+r,u+r,o+r -prune -o -print > files_and_folders
-perm -g+r,u+r,o+r
現在のユーザーがそのファイルを読み取ることができるかどうかに直接関係のない、ファイルのr
3つのセキュリティプリンシパルすべてに(読み取り)アクセス許可が設定されているファイルと一致するだけです。現在のユーザーが読み取ることのできるファイルを見逃す可能性と、読み取ることができないファイルと一致させる可能性の両方があります。
find . -type d ! \( -perm -u+r -o -perm -g+r -o -perm -o+r \) -prune -o -print
は良い解決策になると思います。
-readable
と-perm
-私の以前のコメントを見ると、この例を考えてみます。echo 'hi' > file; sudo chown nobody:nobody file; sudo chmod o-r file; find file -perm -u=r
プリントをfile
、そのユーザーはビットがセットされている読んでいるので、それはに関しnobody
、ユーザーではなく、現在のユーザー。現在のユーザーはこのファイルを読み取ることができません。試してみてくださいcat file
。参照:私のこの答え。
上記のアプローチはMac OS Xのケースに対応していませんが、Mac OS X -readable
はスイッチをサポートしていないため、これにより出力の「アクセス拒否」エラーを回避できます。これは誰かを助けるかもしれません。
find / -type f -name "your_pattern" 2>/dev/null
。
find
たとえば、で他のコマンドを使用している場合、ディレクトリ内の特定のパターンのファイルのサイズを見つけるには、2>/dev/null
次のように動作します。
find . -type f -name "your_pattern" -exec du -ch {} + 2>/dev/null | grep total$
。
これは、指定されたパターンのファイルの合計サイズを返します。2>/dev/null
findコマンドの最後にあるに注意してください。
2>/dev/null
ます。あなたは一部を説明していただけます-exec du -ch {} + 2>/dev/null | grep total$
。
-exec
オプション付きの任意のコマンドを使用して、コマンドによって検出されたファイルまたはディレクトリに対してさらにアクションを実行できますfind
。du -ch file_pattern
一致する各ファイルのサイズを計算し、file_pattern
その出力の最後の行は、に一致したすべてのファイルの総計ですfile_pattern
。のマニュアルページを参照してくださいdu
。grep total
総計を抽出する行をフィルタリングするだけです(これは最後の行です)。
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
ファイル自体が書き込み可能でない場合)-perm
basedソリューションは、引用が示唆するよりも根本的に意図したものとは異なるため、提示する価値はありません。これは、ファイルの所有者に関する純粋にファイル中心のテストですグループ、どちらもコマンド(参照呼び出しユーザーとの任意の保証関係持ってこの答え鉱山のをそれは今あなたの改訂GNUソリューションのように見えないキャッチ許可が起因するエラーを否定した。ファイル。
echo 'hi' > file; sudo chown nobody:nobody file; sudo chmod o-r file; find file -perm -u=r
prints file
で私のポイントを説明します。これは、ユーザー読み取りビットが設定されているためですが、nobody
ユーザーに関連しています、現在のユーザーではありません。現在のユーザーはこのファイルを読み取ることができません。試してみてくださいcat file
。
-perm
。ユーザーの現在のアクセス許可を決定するために機能しないようです。この回答からその代替案を削除しました。
許可が拒否されたという警告だけを回避するには、読み取りから読み取れないファイルを検索から除外して無視するようにfindに伝えます。ORとして式を検索に追加します。
find / \! -readable -prune -o -name '*.jbd' -ls
これは主に(読み取り不可能なファイルを照合してリストから削除する)または( * .jbdのような名前を照合し、[lsを使用して]表示する)ことを示しています。(デフォルトでは、-orを使用しない限り、式はANDで結合されることに注意してください。)2番目の式で-lsが必要です。 。
しかし、システムで実際のファイルを探している場合は、多くのファイルが含まれている/ devを探す必要はないので、次のように、そのディレクトリを除外する式を追加する必要があります。
find / -mount \! -readable -prune -o -path /dev -prune -o -name '*.jbd' -ls
したがって、(読み取り不可能なファイルに一致してリストから削除) OR (パス/ devに一致してリストから削除) OR ( * .jbdのようなファイルに一致して表示)。
使用する
sudo find / -name file.txt
それは愚かで(検索を昇格させるため)、安全ではありませんが、書くのははるかに短いです。
sudo
です。バグfind
や悪意のあるバージョン、または予期しない何かを書き込む不正な呼び出しによってシステム全体がめちゃくちゃになるリスクがあります。これは、通常の権限でこれを実行した場合には起こり得ません。
上記の答えはどれもうまくいきませんでした。私がインターネット上で見つけたものは何にでも焦点を当てています:エラーを隠す。どれも、プロセスのreturn-code / exit-codeを適切に処理しません。bashスクリプト内でコマンドfindを使用して、いくつかのディレクトリを特定し、その内容を検査します。exit-codeを使用してコマンドが成功したかどうかを評価します。値ゼロは機能し、それ以外の場合は失敗します。
上記の答えでマイケルBruxは時々動作します。しかし、失敗するシナリオが1つあります。私は問題を発見し、自分で修正しました。次の場合にファイルを整理する必要があります。
it is a directory AND has no read access AND/OR has no execute access
ここで重要な問題を参照してください:AND / OR。私が読んだ1つの良い推奨条件シーケンスは次のとおりです。
-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 -type!\(-readable -a -executable \) \)-prune \
-o \
\(-type d -a -readable -a-実行可能ファイル-a -name "$ {m_find_name}" \)-print
ここで重要なのは、組み合わせ式の「真ではない」を配置することです。
has read access AND has execute access
それ以外の場合は、完全なアクセス権がありません。つまり、プルーニングします。これは、以前に提案されたソリューションが失敗した1つのシナリオで機能することが証明されました。
コメント欄に質問の技術的な詳細を以下に示します。詳細が多すぎる場合はお詫び申し上げます。
nice
とfind $HOME -maxdepth 5 -follow ...
?
${m_find_name}
)、そして、質問に関連していないいくつかのオプションが含まれています(nice
、/home*
、-maxdepth 5
、-follow
)。汎用性を維持しながら、「読み取り可能で実行可能ではないディレクトリのフィルタリング」という特定の問題に対処する回答をより簡潔に追加しました。
あなたはgrep -v invert-matchを使うことができます
-v, --invert-match select non-matching lines
このような:
find . > files_and_folders
cat files_and_folders | grep -v "permission denied" > files_and_folders
魔法にすべき
-= MacOSの場合=-
エイリアスを使用して新しいコマンドを作成します。〜/ .bash_profile行に追加するだけです。
alias search='find / -name $file 2>/dev/null'
そして新しいターミナルウィンドウでそれを呼び出すことができます:
$ file=<filename or mask>; search
例えば:
$ file = etc; 探す
CSHまたはTCSHを使用している場合、解決策は次のとおりです。
( find . > files_and_folders ) >& /dev/null
端末に出力したい場合:
( find . > /dev/tty ) >& /dev/null
find . 2>&1 > files_and_folders | grep -v 'Permission denied' >&2
ですか?