Bagaimana saya membuat find mengikuti sebagian besar, tetapi tidak semua, tautan simbolik?

10

OS dan direktori home saya menggunakan SSD. Saya menyimpan beberapa file besar di hard disk, dan symlink dari direktori home saya ke hard disk (mis. ~ / Video / Film adalah symlink ke / mnt / hdd / Films). Saya juga memiliki sejumlah awalan Wine, yang masing-masing memiliki dosdevices / z: disinkronkan dengan /.

Jadi, jika saya menggunakan find tanpa -L, itu akan kehilangan semua yang ada di hard disk. Tetapi jika saya menggunakan find dengan -L, itu berakhir dalam satu lingkaran karena symlink Wine ke /.

Apakah ada cara yang masuk akal untuk menyelesaikan ini, sehingga menemukan pencarian di tempat yang saya inginkan? Secara intuitif, saya menginginkan sesuatu di sepanjang baris "follow symlinks, kecuali mereka berada di bawah direktori yang disebut dosdevices". "Ikuti symlink yang mengarah ke sesuatu di hard disk" juga akan berfungsi.

Mark Raymond
sumber

Jawaban:

11

The -pruneutama mengatakan findtidak recurse bawah direktori.

find -L -path ~/.wine/dosdevices -prune -o -type f -name 'My Favorite Movie.*' -print

Jika Anda ingin menggunakan -lnamedalam kondisi Anda, Anda tidak dapat menggunakan -Lopsi, karena -Lsebagian besar predikat bertindak berdasarkan target tautan, termasuk -lname. Rekomendasi saya dalam hal ini adalah menggunakan direktori home dan root hard disk sebagai akar pencarian Anda.

find ~ /mnt/hdd -xtype f -name 'My Favorite Movie.*'

Anda mungkin berlari find ~ -type l …untuk mengumpulkan daftar tautan simbolik dan menggunakannya sebagai root tambahan.

( IFS=$'\n'; set -f;
  find ~ $(find ~ -type l -lname '/mnt/hdd/*') \
       -xtype f -name 'My Favorite Movie.*' )

Jika Anda benar-benar ingin muncul kembali di bawah tautan simbolis, Anda dapat mengecualikan tautan simbolis tertentu berdasarkan target alih-alih dengan nama. Namun Anda hanya dapat mengecualikan daftar terbatas, bukan pola atau subtree dengan cara ini.

find -L \( -samefile /exclude/this -o -samefile ~/and/that \) -prune -o \
     -type f -name 'My Favorite Movie.*' -print

Anda dapat menggunakan kriteria lain seperti ! -writable(file yang Anda tidak memiliki izin menulis), tetapi saya rasa GNU find tidak memiliki cara untuk berulang di bawah tautan simbolis hanya jika teks targetnya cocok dengan ekspresi tertentu.

Anda dapat membangun findperintah yang melakukan hampir semua yang Anda inginkan kecuali untuk tidak mengecualikan tautan simbolis yang cukup, jalankan find2perl untuk mengonversi kueri menjadi skrip Perl, dan sedikit mengubah skrip Perl. Ada banyak sakelar GNU yang menemukan find2perl tidak mengenalinya.

Gilles 'SANGAT berhenti menjadi jahat'
sumber
Terima kasih! -prunehanyalah hal yang saya cari. Saya telah menemukan bahwa find ~ \( -lname ~ -o -lname ~/\* -o -lname / \) -xtype ddaftar semua symlink yang tidak ingin saya ikuti; Saya sekarang mencoba menemukan cara untuk menggunakan kueri itu untuk memangkas.
Mark Raymond
@MarkRaymond Prinsip umumnya adalah find ~ <negative criteria> -prune -o <positive criteria> -print, jadifind ~ \( -lname ~ -o -lname ~/\* -o -lname / \) -xtype d -prune -o <whatever it is you want> -print
Gilles 'SO- berhenti menjadi jahat'
@ Giles - berfungsi dengan baik tanpa -L, tetapi begitu saya menambahkan -L, ekspresi -lname tidak berfungsi lagi (seperti yang dikatakan halaman manual tidak akan). Jadi pada dasarnya saya kemudian membutuhkan beberapa kondisi untuk mengikuti symlink dan yang lainnya tidak!
Mark Raymond
Saya tidak bisa memikirkan cara untuk melakukan apa yang Anda inginkan dengan menemukan. Lihat hasil edit saya untuk beberapa perkiraan.
Gilles 'SANGAT berhenti menjadi jahat'
1

Untuk mencari SEMUA tautan, ini berfungsi untuk saya:

find -L . -name \*.txt
Jim
sumber
0

Berapa banyak symlink ke hard disk yang Anda miliki? Jika tidak terlalu banyak satu solusi adalah tidak menggunakan "-L" sambil secara eksplisit menentukan symlink yang ingin Anda ikuti pada baris perintah find. Sesuatu seperti:

find .  ~/Videos/Films -name '*file I want*' ...

Ini akan mencari direktori saat ini (".") Serta symlink "~ / Video / Film" tetapi tidak akan turun ke symlink lain.

John1024
sumber
0

Solusi lain yang mengatasi masalah (setidaknya untuk kasus saya) adalah menggunakan bind mounts alih-alih tautan simbolik untuk direktori pada hard disk. Ini dilakukan dengan menambahkan entri /etc/fstabseperti ini:

/mnt/hdd/Films /home/mark/Videos/Films none bind 0 0

Mark Raymond
sumber