UNIXのfindコマンドをマスターするにはどうすればよいですか?


11

findの使用はかなり進んでいると思いますが、使用するたびに-execオプションを閉じる方法を思い出せません。私はそれを使うたびに読書にかなりの時間を費やしています。私は単にそれを十分に使用していないか、自分自身を期待しすぎていませんか?イライラする典型的な例から始めましょう。

ディレクトリ構造には、すべての不正なアクセス許可が隠されたファイルシンボリックリンクなどのファイルがあります。所有権を妥当な値に変更したい

find . -type f -exec chown username {} \;
find . -type d -exec chown username {} \;
find . -type d -exec chgrp usergroup {} \;
find . -type f -exec chgrp usergroup {} \;

(エンディングが後方にある場合は私を許してください...私は1時間前にそれを見て、それでも私はわからない)

しかし、マウント、シンボリックリンクなどのために実行するのが怖いです。chmod。*の究極の愚かさを作り、以前にそれを上に再帰させました。-xdevはパーティションをまたぐことを忘れますが、シンボリックリンクであるディレクトリ内にあるファイルがどうなるかはわかりません。

それでは、重要なファイルを殺すことができるこの獣をどうやってマスターするのでしょうか?

以下の最適な提案の整理と要約を更新します。

  1. 他の練習ディレクトリにリンクしてマウントした練習ディレクトリを用意します。
  2. 直感的でないexecコマンドではなくxargsを使用してください。
  3. 健全性と安全性のために-exec echo {}を使用します
  4. セミコロンは特別であり、あなたはそれをエスケープしているので、エスケープ文字が最初です
  5. -orコマンドは、選択基準を組み合わせるのに役立ちます。

私はprint0について少し混乱していますが、xargsは、私が試し、回避しようとする、一目で理解するのが容易ではないことについて、常に少しばかりです。


1
私もそれを覚えていないので、xargsにパイプします。
共振器

2
適切なコマンドの作成に満足したら、\ではなく+で実行することを検討してください。execコマンドはあまり頻繁に呼び出されないため、+を使用すると実行速度が速くなります。
wzzrd

wzzrd、\ではなく+の使用に関するすばらしいヒント。
ダニエルローソン

回答:


19

さて、-exec構文に関する限り、多くの人と同じように、あきらめて使用することができますxargs

find . -type f | xargs chown username

(またはスペースを含むファイルとその他のナンセンスな安全なバージョン)

find . -type f -print0 | xargs -0 chown username

または、セミコロンで行うには正しいことを覚えしようとする、あなたの頭にドリルダウンするために必要なもの、あなたがするセミコロンを使用していることである終了コマンド-exec実行中であることを、あなたがする必要が逃れることは特別なを持っているので、セミコロンを意味するbash。これがバックスラッシュセミコロンである理由です。あなたは持っているように見える{}置換部分は大丈夫。

ファイルの削除などに関して、あなたが話しているような大きくて危険なものを実行している場合、最初にこれを行います:

find . -type f -exec echo chown username {} \;

結果を確認します。これは基本的に「ドライラン」であり、許可すると実行されるコマンドが表示されます。間違いなく良い習慣です。助けにはなりません.*問題が、あなたは今、そのいずれかを実行しないように知っています。:)


1
+!「エコー」練習のためのドライラン。私は常に大きな変化のためにこれを使用します
スティーブフォリー

3

誰もまだ次のオプションについて言及していないことに驚いています。

find . -type f -ok chown username {} \;

この構文は、コマンドを実行する前に確認します。一致するファイルの数が比較的少ないと予想される場合に最適です。各ファイルの入力を求めるプロンプトが表示されるためです。

いくつかの答えは言及xargsしていますが、GNUではそれも不要であることがわかります:

find . -type f -exec chown username {} \+

通常、+はエスケープする必要はありませんが、とにかくそうする習慣を身に付けておくと便利です。


プラス記号の性質を説明できますか?正確に何をしているのですか?シェルがそれを処理するか、コマンドですか。これは興味深いトピックなので、gnu-findのソースコードをダウンロードするつもりです。
ojblass 09年

findはそれを処理しています。そのオプションの詳細については、man findを参照してください。
カミルKisiel 09年

3

これがmanの目的です: 物事を覚えるのは難しいかもしれませんそれが* nixコマンドにmanページが含まれている理由です。構文のリマインダーについては、manページのACTIONセクションでいつでも確認できますman find。マニュアルページはフレンドリーではないように思えるかもしれませんが、読むのが上手になれば非常に便利です。

フロントエンドまたはラッパーの作成: GNU findをもっと使いたいと思ったとき、python、glade、pygtkでfindコマンドを生成するfindのGUIフロントエンドを書きました。これを本当によく知りたいなら、これは良い練習です。

練習ディレクトリを持っている: 最後に、「エコー」のようなものがそれをカットしないときに強力なコマンドで遊ぶために、私のホームディレクトリに常に「スクラップ」ディレクトリがあります。シェル拡張を使用して、次のようなファイルをすばやく作成できます。

for i in {1..100}; do touch "$i"; done

奇妙な練習用ディレクトリは、私が考えたことのないものです。
ojblass 09年

1

また、検索式を「-and」および「-or」演算子と組み合わせることもできます。-暗黙的です:

find . -type f -name "plainfile" ...

と同じです

find . -type f -and -name "plainfile" ...

or演算子は、4つのコマンドのリストを2つに減らすことができます。

find . -type d -or -type f ...

最後に、findとは関係ありませんが、chownはグループも設定できます。したがって、名前のスペースに対処することもできます:

find . -type d -or -type f -exec chown username:usergroup '{}' \;

-またはビジネスで見つけるもの。[原文]
ojblass

@ojblass:findは、「and」または「or」を使用して式を結合します。デフォルトでは、「-and」も「-or」も指定されていない場合、「-and」が暗黙的に使用されます。したがって、「find -type d -type f」と入力しても、ディレクトリファイルは何もないため、何も検索されません。
スティーブフォリー

0

終了するときは、使用することを考えています。多くのプログラミング言語と同様に、それをエスケープします。それをエスケープする必要があることを覚えておいてください。


0

使用しているfindのバージョンに応じて、役立つオプションがあります。GNU findはおそらく最も強力であり、これは2番目の(暗黙の)質問に役立つ可能性があります

たとえば、デフォルトの動作はシンボリックリンクを逆参照することではありませんが、オーバーライドできます。-mountオプションは、マウントポイントを横断する検索を停止します

ローカルのマニュアルページを見てください


0

xargsオプションは、各ファイルに対してコマンドを1回実行しないため、-execオプションよりも高速であると主張する人もいますが、些細な時間を要する大規模なジョブ以外については心配しません。

個人的には、通常はexecなしでfindを実行します

find /path/to/dir -name whatever

出力が正しいことを確認してから、そのリストでコマンドを実行します。

chown user:group `find /path/to/dir -name whatever`

物事を「しない」方法の完璧な例。スペースを含むファイル名。
イアンケリング

うん、それは潜在的な問題であり、私はおそらく認めるべきだった。しかし、私のポイントは、何かを実行する前に検索出力を読むことで、スペースやその他のファイル名の狂気を見つけることでした。
受信2:09で

0

一部のシェル(bashではない)では、適切な動作のために{}をエスケープします。

\{\} or '{}'

findマニュアルは、findをマスターするのに適しています。


いいえ、そうではありません。findはそのまま{}で実行できます。これらは、findコマンドの一部です。findコマンドの結果で置き換えられるトークンです。関数を定義したり変数を呼び出したりするときは、bashで何かを意味するだけなので、元の質問のように使用できます。
wzzrd 2009年

そのmanページから。bashには適用されないと言って更新しました。
イアンケリング

0

このようなことを行う前に、このコマンドを実行するディレクトリが/ usrまたは/ etcと同じファイルシステムにないことを確認してください。(そうでない場合、ホームディレクトリに/ etc / passwdまたは/ bin / shへのハードリンクがある場合は、それらの所有権を与えたばかりで、副作用としてマシンを所有しています)。

ディレクトリを再帰処理し、すべてのファイル/ディレクトリをchownしたい場合は、簡単な

chown -Rh user:usergroup user /

それを行います。必ず -hを使用してください。そうしないと、chownはシンボリックリンクをたどります。


これはクロスプラットフォームだとは思いません。練習環境で示されているように、247Kのファイルでも失敗します。理由はわかりません。
ojblass 09年

クロスプラットフォームの問題を発見したよりも、バグを発見したと思います。失敗したときの終了バージョンはどのバージョンですか?私が知る限り、それは最初の初期のbsdバージョンに由来します。それは間違いなくsunos 5.3およびultrixとirixにあります。失敗するまでに何回処理されますか?
クリス

確かに、AIX 5.3、AIX 5.2で動作しますが、AIX 4.3、NCR、HP 11、HP 10.20、またはDSLディストリビューションでは動作しません。すべての場合、60kファイルまたはその近くで失敗するようです。
ojblass 09年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.