Bagaimana cara menguasai perintah menemukan UNIX?

11

Saya pikir saya cukup maju dalam menggunakan find tetapi SETIAP kali saya menggunakannya, saya tidak bisa seumur hidup saya mengingat metode untuk menutup opsi -exec. Saya menghabiskan banyak waktu membaca setiap kali saya menggunakannya. Apakah saya tidak cukup menggunakannya atau berharap terlalu banyak pada diri saya sendiri? Mari kita mulai dengan contoh khas yang membuat saya frustrasi.

Struktur direktori memiliki file dengan semua izin yang salah, file, tautan simbolis, dll. Saya ingin mengubah kepemilikan ke nilai yang wajar

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

(Maafkan saya jika endingnya terbalik ... Saya melihatnya satu jam yang lalu dan saya masih tidak yakin)

Tetapi saya takut untuk menjalankannya karena mount, tautan simbolik, dll. Saya telah membuat kesalahan besar chmod. * Dan membuatnya berulang pada saya sebelumnya. Saya tahu -xdev akan menghapus partisi tetapi saya tidak yakin apa yang akan terjadi pada file yang hidup di dalam direktori yang merupakan tautan simbolik.

Jadi bagaimana seseorang bisa menguasai makhluk buas ini yang bisa membunuh file-file penting?

Perbarui pemangkasan saran terbaik di bawah ini dan rangkum:

  1. Miliki direktori latihan yang ditautkan dan dipasang ke direktori latihan lainnya.
  2. Gunakan xargs daripada perintah exec non-intuitif.
  3. Gunakan -exec echo {} untuk kewarasan dan keamanan
  4. Semi usus besar adalah khusus dan Anda melarikan diri karena itu char melarikan diri adalah yang pertama
  5. Perintah -atau dapat membantu Anda menggabungkan kriteria seleksi.

Saya sedikit bingung tentang print0 tetapi xargs selalu sedikit pada tidak mudah dimengerti pada praktek pandangan pertama yang saya coba dan hindari.

ojblass
sumber
1
Saya juga tidak dapat mengingatnya, jadi saya hanya mengirimnya ke xargs.
resonator
2
Ketika Anda puas dengan membangun perintah yang tepat, pertimbangkan untuk menjalankannya dengan + alih-alih \; Ini akan berjalan lebih cepat dengan + karena perintah exec akan lebih jarang dipanggil.
wzzrd
wzzrd, tip bagus tentang menggunakan + daripada \;
Daniel Lawson

Jawaban:

19

Nah, sejauh -execsintaks berjalan, Anda bisa melakukan seperti banyak orang, menyerah dan menggunakan xargs:

find . -type f | xargs chown username

(atau versi file-dengan-spasi-dan-omong kosong-di-mereka-aman)

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

Atau, untuk mencoba mengingat hal yang benar untuk dilakukan dengan titik koma, apa yang perlu Anda bor ke kepala Anda adalah bahwa Anda menggunakan titik koma untuk mengakhiri perintah yang -execsedang berjalan, dan Anda harus melarikan diri dari titik koma karena memiliki titik koma. artinya untuk bash. Itulah sebabnya titik koma backslash. Anda tampaknya memiliki bagian {}pengganti oke.

Untuk membunuh file dan sebagainya, jika Anda menjalankan sesuatu yang besar dan berbahaya seperti yang Anda bicarakan, pertama-tama lakukan ini:

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

dan tinjau hasilnya. Ini pada dasarnya adalah "dry run" di mana Anda melihat perintah itu akan berjalan jika Anda membiarkannya. Praktik yang bagus. Tidak akan membantu dengan .*masalah, tetapi Anda tahu untuk tidak melakukannya sekarang. :)

kekacauan
sumber
1
+! untuk latihan dry 'echo'. Saya selalu menggunakan ini untuk perubahan besar
Steve Folly
3

Saya terkejut belum ada yang menyebutkan opsi berikut:

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

Sintaks ini akan mengkonfirmasi perintah sebelum menjalankannya. Ini berfungsi paling baik jika Anda mengharapkan kecocokan Anda menjadi sejumlah kecil file karena itu akan meminta masing-masing.

Beberapa jawaban menyebutkan xargs, tetapi dengan GNU ternyata tidak perlu:

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

Perhatikan bahwa tanda + biasanya tidak perlu diloloskan, tetapi ada baiknya untuk terbiasa dengan kebiasaan itu.

Kamil Kisiel
sumber
Bisakah Anda menjelaskan sifat tanda plus ... apa sebenarnya yang dilakukannya? Apakah shell memprosesnya atau perintah. Saya pikir saya akan mengunduh kode sumber untuk gnu-find karena ini adalah topik yang menarik.
ojblass
find sedang memprosesnya. Baca man temukan untuk mencari tahu lebih lanjut tentang opsi itu.
Kamil Kisiel
3

Inilah gunanya manusia: Sulit untuk mengingat hal-hal, itulah sebabnya * perintah nix mencakup halaman manual. Anda hanya dapat selalu memeriksa bagian ACTION dari halaman manual untuk pengingat pada sintaks: man find. Meskipun halaman manual tampaknya tidak ramah, begitu Anda bisa membacanya, mereka sangat berguna.

Buat Front-End atau Wrapper: Ketika saya ingin menjadi lebih baik di GNU, saya menulis front end GUI untuk find yang menghasilkan perintah menemukan dengan python, glade, dan pygtk. Ini adalah latihan yang baik jika ingin mengenalnya dengan sangat baik.

Punya Direktori Praktek: Terakhir, saya selalu memiliki direktori 'memo' di direktori home saya untuk bermain dengan perintah yang kuat ketika sesuatu seperti 'echo' tidak memotongnya. Anda dapat menggunakan ekspansi shell untuk membuat banyak file dengan cepat seperti:

for i in {1..100}; do touch "$i"; done
Kyle Brandt
sumber
Aneh direktori latihan adalah sesuatu yang tidak pernah saya pertimbangkan.
ojblass
1

Anda juga dapat menggabungkan ekspresi temukan dengan operator '-dan' dan '-atau. -dan tersirat:

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

sama dengan

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

Operator atau dapat mengurangi daftar 4 perintah menjadi 2:

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

Dan akhirnya, tidak terkait untuk menemukan, tetapi chown juga dapat mengatur grup juga. Jadi, mengatasi spasi dalam nama juga kita berakhir dengan:

find . -type d -or -type f -exec chown username:usergroup '{}' \;
Steve Folly
sumber
Apa yang ditemukan dengan -atau bisnis. [Sic]
ojblass
@ojblass: find menggabungkan ekspresi menggunakan 'dan' atau 'atau', secara default jika '-dan' atau '-atau' tidak ditentukan, '-dan' digunakan secara implisit. Jadi ketik 'find -type d -type f' tidak akan menemukan apa-apa karena tidak ada direktori dan file.
Steve Folly
0

Saat menutup saya hanya berpikir untuk menggunakan; suka dengan banyak bahasa pemrograman dan kemudian menghindarinya. Ingatlah bahwa itu perlu untuk diloloskan dan itu datang kepada Anda dengan cukup mudah.

Garry Harthill
sumber
0

Tergantung pada versi menemukan yang Anda gunakan ada beberapa opsi yang dapat membantu Anda. GNU find mungkin yang paling kuat dan ini dapat membantu Anda dengan pertanyaan kedua Anda (tersirat)

Misalnya - perilaku default bukan untuk men-decereference tautan simbolik, tetapi Anda dapat menimpanya; dan opsi -mount berhenti menemukan melintasi titik mount

Lihat di halaman manual lokal Anda


sumber
0

Beberapa orang akan berpendapat bahwa opsi xargs lebih cepat daripada opsi -exec karena tidak akan mengeksekusi perintah sekali untuk setiap file, tetapi saya tidak akan khawatir tentang hal itu untuk apa pun kecuali pekerjaan besar mengambil jumlah waktu yang tidak sepele.

Secara pribadi, saya biasanya menjalankan find tanpa exec

find /path/to/dir -name whatever

pastikan bahwa output terlihat benar, dan kemudian jalankan perintah saya pada daftar itu.

chown user:group `find /path/to/dir -name whatever`
theecereceive
sumber
Contoh sempurna tentang bagaimana "tidak" melakukan sesuatu. Nama file dengan spasi.
Ian Kelling
Yap, itu masalah potensial yang mungkin harus saya akui. Namun poin saya adalah tentang membaca hasil pencarian sebelum mengeksekusi apa pun, di mana Anda akan melihat spasi atau kegilaan nama file lainnya.
theotherreceive
0

Untuk beberapa shell (bukan bash) luput {} untuk perilaku yang benar.

\{\} or '{}'

menemukan manual bagus untuk menguasai find.

Ian Kelling
sumber
Tidak kamu tidak; find berjalan dengan baik dengan {} sebagaimana adanya. Mereka adalah bagian dari perintah find: mereka adalah token yang digantikan oleh hasil dari perintah find. Mereka hanya berarti sesuatu dalam bash ketika mendefinisikan fungsi atau memanggil variabel, jadi Anda bisa menggunakannya seperti dalam pertanyaan asli.
wzzrd
Ini dari halaman manual. Saya memperbarui untuk mengatakan itu tidak berlaku untuk bash.
Ian Kelling
0

Sebelum Anda melakukan hal seperti ini, pastikan direktori tempat Anda menjalankan perintah ini tidak berada di sistem file yang sama dengan / usr atau / etc. (Jika tidak, jika saya memiliki tautan keras ke / etc / passwd atau ke / bin / sh di direktori home saya, Anda baru saja memberi saya kepemilikannya dan sebagai efek samping, saya sekarang memiliki mesin).

Jika Anda ingin berulang melalui direktori dan chown semua file / direktori, sederhana

chown -Rh pengguna: usergroup user /

akan melakukannya. Membuat yakin Anda menggunakan h atau chown akan mengikuti link simbolik.

chris
sumber
Saya tidak berpikir ini adalah platform silang. Juga gagal dengan 247 ribu file seperti yang ditunjukkan oleh lingkungan praktik saya. Saya tidak yakin mengapa.
ojblass
Saya pikir Anda telah menemukan bug lebih dari yang Anda temukan masalah crossplatform. Versi mana dan apa status keluar saat gagal? Sejauh yang saya tahu pertama kali berasal dari versi bsd awal; itu pasti di sunos 5.3 dan ultrix dan irix. Berapa prosesnya sebelum gagal?
chris
Anda benar ini berfungsi pada AIX 5.3, AIX 5.2, tetapi tidak AIX 4.3, NCR, HP 11, HP 10.20, atau distribusi DSL saya. Dalam semua kasus tampaknya gagal pada atau dekat file 60k.
ojblass