ketik 'man find'. Saya pikir '-executable' adalah opsi yang Anda inginkan.
sje397
3
find -executable... tetapi ini tidak menjamin bahwa setiap file yang terdaftar benar-benar akan dieksekusi
William
1
Tidak semua implementasi finddibuat sama. Opsi yang direkomendasikan oleh @ sje397 dan @William mungkin tidak tersedia. Lebih baik menggunakan solusi yang diterima yang ditunjukkan di bawah ini.
Saya tidak menyukai semua proposal yang ditampilkan di bawah ini yang didasarkan pada izin file. Argumentasi: untuk sistem operasi GNU (Ubuntu) saya, dimungkinkan untuk menyetel tanda "x" (dapat dieksekusi) untuk misalnya file teks ASCII. Tidak ada peniruan yang mencegah operasi ini berhasil diselesaikan. Ini hanya membutuhkan kesalahan kecil / bug untuk beberapa file yang tidak dimaksudkan untuk mendapatkan x flag yang ditugaskan. Oleh karena itu solusi gniourf_gniourf 'adalah favorit pribadi saya. Namun, ada kekurangannya bahwa untuk file executable yang dikompilasi silang memerlukan emulator atau perangkat target.
Na13-c
Jawaban:
173
Pada versi GNU, Anda dapat menggunakan -executable:
find .-type f -executable -print
Untuk versi BSD find, Anda dapat menggunakan -permwith +and octal mask:
find .-type f -perm +111-print
Dalam konteks ini "+" berarti "setiap bit ini disetel" dan 111 adalah bit eksekusi.
Perhatikan bahwa ini tidak identik dengan -executablepredikat di GNU find. Secara khusus, -executablemenguji bahwa file tersebut dapat dijalankan oleh pengguna saat ini, sementara -perm +111hanya menguji apakah ada izin eksekusi yang ditetapkan.
Versi lama GNU juga mendukung -perm +111sintaks, tetapi sejak 4.5.12 sintaks ini tidak lagi didukung. Sebaliknya, Anda bisa menggunakan -perm /111untuk mendapatkan perilaku ini.
@sourcejogja Terima kasih. Saya sebenarnya hanya berbicara tentang versi non-GNU dari find (BSD, khususnya) tetapi versi GNU yang lebih lama sebenarnya mendukung sintaks itu juga. Dalam versi yang lebih baru Anda harus menggunakan /bukan +. Lihat jawaban yang diperbarui untuk lebih jelasnya.
Laurence Gonsalves
Memang, saya salah membaca jawaban Anda. Maaf sudah membuatnya lebih rumit :).
sourcejedi
Jika symlink ke file executable juga harus ditemukan, termasuk -Lpilihan: find -L ....
mklement0
Butuh beberapa saat bagi saya untuk memahami implikasi dari "tidak identik dengan predikat-yang dapat dieksekusi" dan "hanya menguji jika ada izin eksekusi yang disetel": Ini berarti bahwa -perm +111dapat menghasilkan positif palsu , yaitu, file yang tidak dapat dijalankan oleh pengguna saat ini. Tidak ada cara untuk meniru -executabledengan menguji izin saja, karena yang diperlukan adalah menghubungkan pengguna file dan identitas grup dengan pengguna saat ini .
mklement0
35
Kiat untuk @ gniourf_gniourf untuk mengatasi kesalahpahaman mendasar.
Jawaban ini mencoba untuk memberikan gambaran umum dari jawaban yang ada dan untuk mendiskusikan kehalusan dan manfaat relatifnya serta untuk memberikan informasi latar belakang , terutama yang berkaitan dengan portabilitas .
Menemukan file yang dapat dieksekusi dapat merujuk ke dua kasus penggunaan yang berbeda :
user-centric : temukan file yang dapat dieksekusi oleh pengguna saat ini .
File-centric : menemukan file yang memiliki (satu atau lebih) executable izin bit set .
Perhatikan bahwa dalam kedua skenario itu mungkin masuk akal untuk menggunakanfind -L ... bukan hanya find ...untuk juga menemukan symlink ke executable .
Perhatikan bahwa kasus file-centric paling sederhana - mencari file yang dapat dieksekusi dengan bit izin yang dapat dieksekusi yang ditetapkan untuk SEMUA tiga prinsip keamanan (pengguna, grup, lainnya) - biasanya akan , tetapi tidak selalu menghasilkan hasil yang sama seperti skenario yang berfokus pada pengguna - dan itu penting untuk memahami perbedaannya.
Berfokus pada pengguna ( -executable)
The jawaban yang diterima commendably merekomendasikan -executable, JIKA GNUfind tersedia.
GNU findhadir dengan sebagian besar distro
Linux
Sebaliknya, platform berbasis BSD, termasuk macOS, hadir dengan BSD find, yang kurang kuat.
Karena tuntutan skenario, -executablehanya mencocokkan file yang dapat dieksekusi oleh pengguna saat ini (ada kasus edge. [1] ).
The BSDfind alternatif yang ditawarkan oleh jawaban yang diterima ( -perm +111) menjawab sebuah yang berbeda , berkas pertanyaan sentris (sebagai jawaban sendiri menyatakan).
Menggunakan hanya -permuntuk menjawab pertanyaan yang berpusat pada pengguna tidak mungkin , karena yang diperlukan adalah menghubungkan pengguna file dan identitas grup dengan pengguna saat ini , sedangkan -permhanya dapat menguji izin file .
Hanya dengan menggunakan fitur POSIXfind , pertanyaan tidak dapat dijawab tanpa menggunakan utilitas eksternal.
Jadi, yang terbaik -permbisa dilakukan (dengan sendirinya) adalah pendekatan dari -executable. Mungkin lebih dekat pendekatan dari -perm +111ini-perm -111 , sehingga untuk menemukan file yang memiliki bit set executable untuk kepala SEMUA keamanan (user, group, lainnya) - pemogokan ini saya sebagai khas skenario dunia nyata. Sebagai bonus, ini juga sesuai dengan POSIX (gunakan find -Luntuk menyertakan symlink, lihat lebih jauh di bawah untuk penjelasannya):
find .-type f -perm -111# or: find . -type f -perm -a=x
Jawaban gniourf_gniourf memberikan padanan yang benar dan portabel-executable , menggunakan-exec test -x {} \;, meskipun dengan mengorbankan kinerja .
Menggabungkan-exec test -x {} \; dengan -perm +111(yaitu, file dengan setidaknya satu set bit yang dapat dieksekusi) dapat membantu kinerja yang exectidak perlu dipanggil untuk setiap file (berikut ini menggunakan padanan yang sesuai dengan POSIX dari BSD find -perm +111/ GNU find -perm /111; lihat lebih jauh di bawah untuk penjelasannya) :
find .-type f \( -perm -u=x -o -perm -g=x -o -perm -o=x \) -exec test -x {} \; -print
File-centric ( -perm)
Untuk menjawab berkas pertanyaan sentris , itu adalah cukup untuk menggunakan POSIX-compliant -permprimer (dikenal sebagai tes dalam terminologi menemukan GNU).
-permmemungkinkan Anda menguji izin file apa pun , bukan hanya kemampuan eksekusi.
Izin ditetapkan sebagai mode oktal atau simbolik . Mode oktal adalah bilangan oktal (mis., 111), Sedangkan mode simbolik adalah string (mis., a=x).
Mode simbolik mengidentifikasi prinsip keamanan sebagai u(pengguna), g(grup) dan o(lainnya), ataua merujuk pada ketiganya. Izin dinyatakan sebagai xdapat dieksekusi, misalnya, dan ditetapkan ke kepala sekolah menggunakan operator =, +dan -; untuk diskusi lengkap, termasuk mode oktal, lihat spesifikasi POSIX untuk chmodutilitas tersebut .
Dalam konteks find:
Mengawali mode dengan- (misalnya, -ug=x) berarti: mencocokkan file yang memiliki semua izin yang ditentukan (tetapi file yang cocok mungkin memiliki izin tambahan).
Memiliki NO prefiks (misalnya 755) berarti: mencocokkan file yang memiliki perizinan lengkap dan tepat ini .
Peringatan : GNU find dan BSD find mengimplementasikan tambahan, tidak standar awalan dengan logika are-ANY-of-the-specific-permission-bits-set , tetapi lakukan dengan sintaks yang tidak kompatibel :
BSD menemukan: +
GNU menemukan: /[2]
Oleh karena itu, hindari ekstensi ini, jika kode Anda harus portabel .
Contoh di bawah ini menunjukkan jawaban portabel untuk berbagai pertanyaan yang berpusat pada file.
Contoh perintah berpusat pada file
catatan:
Pengikut Contoh-contoh ini sesuai dengan POSIX , artinya mereka harus bekerja dalam implementasi yang kompatibel dengan POSIX, termasuk GNU find dan BSD find; secara khusus, ini membutuhkan:
TIDAK menggunakan awalan mode tidak standar + atau /.
Menggunakan bentuk POSIX dari primer operator-logis :
!untuk NOT (GNU find dan BSD find juga allow -not); perhatikan yang \!digunakan dalam contoh untuk melindungi! dari ekspansi riwayat shell
-a untuk AND (GNU find dan BSD find juga mengizinkan -and )
-ountuk OR (GNU find dan BSD find juga allow -or)
Contoh penggunaan mode simbolik , karena lebih mudah dibaca dan diingat.
Dengan mode awalan -, operator =dan +dapat digunakan secara bergantian (misalnya, -u=xsetara dengan -u+x- kecuali jika Anda menerapkannya -xnanti, tetapi tidak ada gunanya melakukan itu).
Gunakan ,untuk bergabung dengan mode parsial; DAN logika tersirat; misalnya, -u=x,g=xberarti bahwa bit yang dapat dieksekusi pengguna dan grup harus disetel.
Mode itu sendiri tidak dapat mengekspresikan pencocokan negatif dalam arti "hanya cocok jika bit ini TIDAK disetel"; Anda harus menggunakan -permekspresi terpisah dengan NOT primer !,.
Perhatikan bahwa primer find (seperti -print, atau -perm; juga dikenal sebagai tindakan dan pengujian di GNU find) secara implisit digabungkan dengan -a(logika AND), -odan mungkin tanda kurung (di-escape sebagai \(dan \)untuk shell) diperlukan untuk mengimplementasikan logika OR.
find -L ...alih-alih hanya find ...digunakan untuk mencocokkan symlink dengan file yang dapat dieksekusi
-Lmenginstruksikan find untuk mengevaluasi target symlink daripada symlink itu sendiri; oleh karena itu, tanpa -L, -type fakan mengabaikan symlink sama sekali.
# Match files that have ALL executable bits set - for ALL 3 security# principals (u (user), g (group), o (others)) and are therefore executable# by *anyone*.# This is the typical case, and applies to executables in _system_ locations# (e.g., /bin) and user-installed executables in _shared_ locations# (e.g., /usr/local/bin), for instance.
find -L .-type f -perm -a=x # -a=x is the same as -ugo=x# The POSIX-compliant equivalent of `-perm +111` from the accepted answer:# Match files that have ANY executable bit set.# Note the need to group the permission tests using parentheses.
find -L .-type f \( -perm -u=x -o -perm -g=x -o -perm -o=x \)
# A somewhat contrived example to demonstrate the use of a multi-principial# mode (comma-separated clauses) and negation:# Match files that have _both_ the user and group executable bit set, while# also _not_ having the other executable bit set.
find -L .-type f -perm -u=x,g=x \! -perm -o=x
[1] Deskripsi dari -executablesejak man findGNU menemukan 4.4.2:
Mencocokkan file yang dapat dieksekusi dan direktori yang dapat dicari (dalam arti resolusi nama file). Ini memperhitungkan daftar kontrol akses dan artefak izin lainnya yang diabaikan oleh pengujian -perm. Tes ini menggunakan panggilan sistem akses (2), dan dengan demikian dapat dibodohi oleh server NFS yang melakukan pemetaan UID (atau root-squashing), karena banyak sistem menerapkan akses (2) di kernel klien sehingga tidak dapat menggunakan informasi pemetaan UID yang disimpan di server. Karena pengujian ini hanya didasarkan pada hasil pemanggilan sistem akses (2), tidak ada jaminan bahwa file yang berhasil diuji ini benar-benar dapat dijalankan.
[2] GNU menemukan versi yang lebih lama dari 4.5.12 juga diperbolehkan prefiks +, tetapi ini pertama kali tidak digunakan lagi dan akhirnya dihapus, karena menggabungkan +dengan mode simbolik menghasilkan kemungkinan hasil yang tidak diharapkan karena diinterpretasikan sebagai topeng izin yang tepat . Jika Anda (a) berjalan di versi sebelumnya 4.5.12 dan (b) membatasi diri untuk oktal mode saja, Anda bisa pergi dengan menggunakan +dengan baik GNU menemukan dan BSD menemukan, tapi itu bukan ide yang baik.
Ini berfungsi, tetapi cukup lambat. Juga, tergantung pada cangkangnya, Anda mungkin harus membungkus atau melepaskan diri dari tempat penahan nama file, seperti '{}'atau \{\}.
Ionoclast Brigham
1
@ mklement0 ini tidak akan menemukan perintah yang dapat dieksekusi oleh saya seperti -executableapakah atau seperti perintah saya.
gniourf_gniourf
1
Terima kasih, @gniourf_gniourf - Saya benar-benar memiliki beberapa kesalahpahaman di sana. Saya mencetak ulang komentar Anda lain di sini, karena saya setidaknya untuk saat menghapus jawaban saya (mungkin untuk dibangkitkan, JIKA ada sesuatu yang diselamatkan): " find . -type f -perm -u=xini tidak setara dengan -executable: -executablecocok dengan semua file yang pengguna dapat mengeksekusi, dan ini termasuk g+xjika saya berada di grup yang tepat atau o+x. Sebenarnya -perm -u=xakan menemukan banyak file yang tidak dapat dieksekusi oleh pengguna, dan melewatkan beberapa file yang dapat dieksekusi oleh pengguna. "
mklement0
1
@IonoclastBrigham: Meskipun harus mengutip {}adalah kebutuhan hipotetis (dan mengutip tidak ada salahnya), dalam praktiknya itu tidak diperlukan dalam shell seperti POSIX dan csh. Apakah Anda tahu kerang mana yang diperlukan?
mklement0
4
@IonoclastBrigham: Menarik, terima kasih; jadi, dalam fish, {}memang harus di-escape sebagai salah satu '{}'atau \{\}. Perhatikan bahwa bash,, kshdan zshberikan jenis ekspansi brace yang sama; Namun, mereka mencetak token tanpa tanda kutip {}apa adanya (dan dengan demikian: tidak perlu melarikan diri), karena mereka TIDAK menganggapnya sebagai ekspresi kurung kurawal yang valid (mereka membutuhkan setidaknya 2 token, atau ekspresi urutan numerik yang valid), sedangkan fish dianggap {}sebagai kurung kurawal yang valid ekspresi yang menghasilkan string kosong .
mklement0
9
Anda bisa menggunakan -executabletest flag:
-executable
Matches files which are executable and directories which are
searchable (in a file name resolution sense).
-executable seharusnya merupakan opsi yang tidak diketahui.
sebenarnya
4
Apakah itu ekstensi GNU Find? Karena tagnya adalah Unix, bukan Linux, paling tidak ekstensi GNU perlu didokumentasikan seperti itu.
Jonathan Leffler
3
Pilihan ini tidak didukung oleh perintah BSD find yang terdapat setidaknya di OS X. Ini adalah ekstensi GNU, tetapi mungkin didukung oleh jenis find lainnya.
Ionoclast Brigham
FWIW, saya menemukan ini bukan pada sles 10, tetapi pada sles> = 11 (sedikit terbakar olehnya)
Peter Turner
Perhatikan bahwa ini tidak benar-benar mendapatkan semua contoh. Dalam kasus saya, saya memiliki file yang saya miliki -rw-r-xr-xyang -executabletidak dapat dideteksi
Dezza
2
Ini berhasil untuk saya & berpikir untuk berbagi ...
find ./-type f -name "*"-not -name "*.o"-exec sh -c '
case "$(head -n 1 "$1")" in
?ELF*) exit 0;;
MZ*) exit 0;;
#!*/ocamlrun*)exit0;;
esac
exit 1
' sh {} \; -print
@ Daniel Alder, versi find mana yang Anda gunakan? Saya tidak menemukan opsi -mime in find (GNU findutils) 4.4.2
AjayKumarBasuthkar
@tripleee +1. menggunakan 'file' & / 'mimetype' adalah ide yang bagus atau temukan versi yang mendukung -mime lebih baik, Juga bertanya-tanya apakah 'file' / 'mimetype' memiliki opsi untuk memfilter dan menampilkan hanya file yang dapat dieksekusi.
AjayKumarBasuthkar
2
find .-executable -type f
tidak benar-benar menjamin bahwa file tersebut dapat dieksekusi, ia akan menemukan file dengan bit eksekusi yang ditetapkan. Jika kamu melakukan
chmod a+x image.jpg
pencarian di atas akan berpikir image.jpg adalah eksekusi bahkan jika itu benar-benar gambar jpeg dengan bit eksekusi set.
Dalam contoh di atas nama path lengkap file ada di bidang terakhir dan harus mencerminkan di mana Anda mencarinya dengan awk "NAME = $ (awk '{print $ NF}' <<< $ LINE)" jika nama file ada di tempat lain di string keluaran find Anda perlu mengganti "NF" dengan posisi numerik yang benar. Jika pemisah Anda bukan spasi, Anda juga perlu memberi tahu awk apa pemisah Anda.
Yang perlu diketahui tentang mdfindOSX. Perhatikan bahwa perintah Anda melaporkan file executable Unix untuk seluruh sistem . mdfind -onlyin . 'kMDItemContentType=public.unix-executable'membatasi hasil ke subpohon direktori saat ini. Tempat menarik kecil: membatasi pencarian ke direktori tertentu saja (tanpa subfolder) tampaknya tidak didukung. Symlink ke file yang dapat dieksekusi tampaknya tidak pernah disertakan. Anehnya, setelah mdfindmenemukan file yang dapat dieksekusi, kemudian menghapus bit yang dapat dieksekusi tidak diambil.
mklement0
Saya rasa saya telah menemukan bug dalam cara Spotlight mendeteksi / tidak mendeteksi file Unix yang dapat dieksekusi; Saya telah melaporkan bug ke Apple, dan juga di openradar.me/20162683 . Saya mendorong Anda - dan siapa pun yang tertarik dengan fungsi ini - untuk juga melaporkan
mklement0
(Maaf atas kebingungan komentarnya; mudah-mudahan, sekarang sudah benar) mdfind -onlyin . 'kMDItemContentType=public.unix-executable'berperilaku seperti find . -type f -perm +111 -printitu. Artinya, ia menemukan file dengan setiap bit set executable, yang dapat menghasilkan positif palsu (meskipun yang mungkin tidak menjadi masalah dalam praktek) - untuk benar-benar hanya menemukan file executable oleh pengguna saat menggunakan BSD menemukan, melihat jawaban @ gniourf_gniourf ini. Menggunakan findsolusi berbasis memiliki keuntungan bahwa Anda dapat menemukan symlink ke file yang dapat dieksekusi juga, jika diinginkan (opsi -L), yang mdfindtampaknya tidak dapat dilakukan.
mklement0
1
@ mklement0 jawaban saya menghindari hiasan - untuk mencoba dan memahami intinya - tapi ya, Anda hampir tidak akan pernah menggunakan formulir ini "tanpa noda". opsi lain - tidak yakin apakah itu muncul - adalah globbing lama yang bagus .. ls /Applications/**/*(*)di zshshell
Alex Grey
Terima kasih atas zshtip praktisnya - tidak tahu itu; (Tampaknya Anda dapat baik mencocokkan executable ( *) atau symlink ( @), tetapi tidak keduanya, kan?). Adapun poin awal Anda: Biarkan saya tegaskan: find . -type f -perm +a=xakan melakukan apa yang dilakukan mdfindperintah Anda, sambil memberikan lebih banyak fleksibilitas. Anda bahkan dapat memformulasi ulang agar sesuai dengan POSIX.
mklement0
1
Jawaban mudahnya adalah: "file yang dapat dieksekusi ada di direktori yang terdapat dalam variabel PATH" tetapi itu tidak akan benar-benar menemukan file yang dapat dieksekusi dan bisa saja kehilangan banyak file yang dapat dieksekusi.
Saya tidak tahu banyak tentang mac, tetapi saya pikir "mdfind 'kMDItemContentType = public.unix-executable'" mungkin melewatkan hal-hal seperti skrip yang diinterpretasikan
Jika tidak masalah bagi Anda untuk menemukan file dengan kumpulan bit yang dapat dieksekusi (terlepas dari apakah mereka benar-benar dapat dieksekusi) maka tidak masalah untuk melakukannya
find .-type f -perm +111-print
jika didukung opsi "-executable" akan membuat filter lebih lanjut melihat acl dan artefak izin lainnya tetapi secara teknis tidak jauh berbeda dengan "-pemr +111".
Mungkin di masa mendatang find akan mendukung "-magic" dan membiarkan Anda mencari secara eksplisit file dengan id ajaib tertentu ... tetapi kemudian Anda harus menentukan untuk mendenda semua format yang dapat dieksekusi id ajaib.
Saya tidak mengetahui cara mudah yang benar secara teknis untuk unix.
Jadi jika Anda benar-benar ingin menemukan jenis file yang dapat dieksekusi (misalnya skrip, ELF binari dll .. dll ..) bukan hanya file dengan izin eksekusi maka Anda mungkin ingin melakukan sesuatu yang lebih seperti ini (di mana direktori saat ini. Dapat diganti dengan apapun direktori yang Anda inginkan):
Meskipun jika Anda menggunakan OS X, ia hadir dengan utilitas kecil yang tersembunyi di suatu tempat bernama is_exec yang pada dasarnya menggabungkan tes kecil itu untuk Anda sehingga Anda dapat mempersingkat baris perintah jika Anda menemukannya. Tetapi cara ini lebih fleksibel karena Anda dapat dengan mudah mengganti tes == dengan tes = ~ dan menggunakannya untuk memeriksa properti yang lebih kompleks seperti file teks biasa yang dapat dieksekusi atau info lain apa pun yang dikembalikan oleh perintah file Anda.
Aturan pasti untuk kutipan di sini cukup buram, jadi saya akhirnya mengerjakannya dengan coba-coba tetapi saya ingin mendengar penjelasan yang benar.
Saya memiliki masalah yang sama, dan jawabannya ada di kode sumber dmenu : utilitas stest dibuat untuk tujuan itu. Anda dapat mengkompilasi file 'stest.c' dan 'arg.h' dan itu akan berfungsi. Ada halaman manual untuk penggunaan, yang saya taruh di sana untuk kenyamanan:
STEST(1)GeneralCommandsManual STEST(1)
NAME
stest - filter a list of files by properties
SYNOPSIS
stest [-abcdefghlpqrsuwx][-n file][-o file][file...]
DESCRIPTION
stest takes a list of files and filters by the
files' properties, analogous to test(1). Files
which pass all tests are printed to stdout. If no
files are given, stest reads files from stdin.
OPTIONS
-a Test hidden files.
-b Test that files are block specials.
-c Test that files are character specials.
-d Test that files are directories.
-e Test that files exist.
-f Test that files are regular files.
-g Test that files have their set-group-ID
flag set.
-h Test that files are symbolic links.
-l Test the contents of a directory given as
an argument.
-n file
Test that files are newer than file.
-o file
Test that files are older than file.
-p Test that files are named pipes.
-q No files are printed, only the exit status
is returned.
-r Test that files are readable.
-s Test that files are not empty.
-u Test that files have their set-user-ID flag
set.
-v Invert the sense of tests, only failing
files pass.
-w Test that files are writable.
-x Test that files are executable.
EXIT STATUS
0 At least one file passed all tests.
1 No files passed all tests.
2 An error occurred.
SEE ALSO
dmenu(1), test(1)
dmenu-4.6 STEST(1)
find -executable
... tetapi ini tidak menjamin bahwa setiap file yang terdaftar benar-benar akan dieksekusifind
dibuat sama. Opsi yang direkomendasikan oleh @ sje397 dan @William mungkin tidak tersedia. Lebih baik menggunakan solusi yang diterima yang ditunjukkan di bawah ini.Jawaban:
Pada versi GNU, Anda dapat menggunakan
-executable
:Untuk versi BSD find, Anda dapat menggunakan
-perm
with+
and octal mask:Dalam konteks ini "+" berarti "setiap bit ini disetel" dan 111 adalah bit eksekusi.
Perhatikan bahwa ini tidak identik dengan
-executable
predikat di GNU find. Secara khusus,-executable
menguji bahwa file tersebut dapat dijalankan oleh pengguna saat ini, sementara-perm +111
hanya menguji apakah ada izin eksekusi yang ditetapkan.Versi lama GNU juga mendukung
-perm +111
sintaks, tetapi sejak 4.5.12 sintaks ini tidak lagi didukung. Sebaliknya, Anda bisa menggunakan-perm /111
untuk mendapatkan perilaku ini.sumber
find: invalid mode ‘+111’
pada findutils 4.5.11 4.fc20./
bukan+
. Lihat jawaban yang diperbarui untuk lebih jelasnya.-L
pilihan:find -L ...
.-perm +111
dapat menghasilkan positif palsu , yaitu, file yang tidak dapat dijalankan oleh pengguna saat ini. Tidak ada cara untuk meniru-executable
dengan menguji izin saja, karena yang diperlukan adalah menghubungkan pengguna file dan identitas grup dengan pengguna saat ini .Kiat untuk @ gniourf_gniourf untuk mengatasi kesalahpahaman mendasar.
Jawaban ini mencoba untuk memberikan gambaran umum dari jawaban yang ada dan untuk mendiskusikan kehalusan dan manfaat relatifnya serta untuk memberikan informasi latar belakang , terutama yang berkaitan dengan portabilitas .
Menemukan file yang dapat dieksekusi dapat merujuk ke dua kasus penggunaan yang berbeda :
Perhatikan bahwa dalam kedua skenario itu mungkin masuk akal untuk menggunakan
find -L ...
bukan hanyafind ...
untuk juga menemukan symlink ke executable .Perhatikan bahwa kasus file-centric paling sederhana - mencari file yang dapat dieksekusi dengan bit izin yang dapat dieksekusi yang ditetapkan untuk SEMUA tiga prinsip keamanan (pengguna, grup, lainnya) - biasanya akan , tetapi tidak selalu menghasilkan hasil yang sama seperti skenario yang berfokus pada pengguna - dan itu penting untuk memahami perbedaannya.
Berfokus pada pengguna (
-executable
)The jawaban yang diterima commendably merekomendasikan
-executable
, JIKA GNUfind
tersedia.find
hadir dengan sebagian besar distro Linux-executable
hanya mencocokkan file yang dapat dieksekusi oleh pengguna saat ini (ada kasus edge. [1] ).The BSD
find
alternatif yang ditawarkan oleh jawaban yang diterima (-perm +111
) menjawab sebuah yang berbeda , berkas pertanyaan sentris (sebagai jawaban sendiri menyatakan).-perm
untuk menjawab pertanyaan yang berpusat pada pengguna tidak mungkin , karena yang diperlukan adalah menghubungkan pengguna file dan identitas grup dengan pengguna saat ini , sedangkan-perm
hanya dapat menguji izin file .Hanya dengan menggunakan fitur POSIX
find
, pertanyaan tidak dapat dijawab tanpa menggunakan utilitas eksternal.Jadi, yang terbaik
-perm
bisa dilakukan (dengan sendirinya) adalah pendekatan dari-executable
. Mungkin lebih dekat pendekatan dari-perm +111
ini-perm -111
, sehingga untuk menemukan file yang memiliki bit set executable untuk kepala SEMUA keamanan (user, group, lainnya) - pemogokan ini saya sebagai khas skenario dunia nyata. Sebagai bonus, ini juga sesuai dengan POSIX (gunakanfind -L
untuk menyertakan symlink, lihat lebih jauh di bawah untuk penjelasannya):Jawaban gniourf_gniourf memberikan padanan yang benar dan portabel
-executable
, menggunakan-exec test -x {} \;
, meskipun dengan mengorbankan kinerja .Menggabungkan
-exec test -x {} \;
dengan-perm +111
(yaitu, file dengan setidaknya satu set bit yang dapat dieksekusi) dapat membantu kinerja yangexec
tidak perlu dipanggil untuk setiap file (berikut ini menggunakan padanan yang sesuai dengan POSIX dari BSD find-perm +111
/ GNU find-perm /111
; lihat lebih jauh di bawah untuk penjelasannya) :File-centric (
-perm
)-perm
primer (dikenal sebagai tes dalam terminologi menemukan GNU).-perm
memungkinkan Anda menguji izin file apa pun , bukan hanya kemampuan eksekusi.111
), Sedangkan mode simbolik adalah string (mis.,a=x
).u
(pengguna),g
(grup) dano
(lainnya), ataua
merujuk pada ketiganya. Izin dinyatakan sebagaix
dapat dieksekusi, misalnya, dan ditetapkan ke kepala sekolah menggunakan operator=
,+
dan-
; untuk diskusi lengkap, termasuk mode oktal, lihat spesifikasi POSIX untukchmod
utilitas tersebut .find
:-
(misalnya,-ug=x
) berarti: mencocokkan file yang memiliki semua izin yang ditentukan (tetapi file yang cocok mungkin memiliki izin tambahan).755
) berarti: mencocokkan file yang memiliki perizinan lengkap dan tepat ini .+
/
[2]Contoh perintah berpusat pada file
catatan:
+
atau/
.!
untuk NOT (GNU find dan BSD find juga allow-not
); perhatikan yang\!
digunakan dalam contoh untuk melindungi!
dari ekspansi riwayat shell-a
untuk AND (GNU find dan BSD find juga mengizinkan-and
)-o
untuk OR (GNU find dan BSD find juga allow-or
)-
, operator=
dan+
dapat digunakan secara bergantian (misalnya,-u=x
setara dengan-u+x
- kecuali jika Anda menerapkannya-x
nanti, tetapi tidak ada gunanya melakukan itu).,
untuk bergabung dengan mode parsial; DAN logika tersirat; misalnya,-u=x,g=x
berarti bahwa bit yang dapat dieksekusi pengguna dan grup harus disetel.-perm
ekspresi terpisah dengan NOT primer!
,.-print
, atau-perm
; juga dikenal sebagai tindakan dan pengujian di GNU find) secara implisit digabungkan dengan-a
(logika AND),-o
dan mungkin tanda kurung (di-escape sebagai\(
dan\)
untuk shell) diperlukan untuk mengimplementasikan logika OR.find -L ...
alih-alih hanyafind ...
digunakan untuk mencocokkan symlink dengan file yang dapat dieksekusi-L
menginstruksikan find untuk mengevaluasi target symlink daripada symlink itu sendiri; oleh karena itu, tanpa-L
,-type f
akan mengabaikan symlink sama sekali.[1] Deskripsi dari
-executable
sejakman find
GNU menemukan 4.4.2:[2] GNU menemukan versi yang lebih lama dari 4.5.12 juga diperbolehkan prefiks
+
, tetapi ini pertama kali tidak digunakan lagi dan akhirnya dihapus, karena menggabungkan+
dengan mode simbolik menghasilkan kemungkinan hasil yang tidak diharapkan karena diinterpretasikan sebagai topeng izin yang tepat . Jika Anda (a) berjalan di versi sebelumnya 4.5.12 dan (b) membatasi diri untuk oktal mode saja, Anda bisa pergi dengan menggunakan+
dengan baik GNU menemukan dan BSD menemukan, tapi itu bukan ide yang baik.sumber
Sehingga memiliki kemungkinan lain 1 untuk menemukan file yang dapat dieksekusi oleh pengguna saat ini:
(perintah uji di sini adalah yang ditemukan di PATH, sangat mungkin
/usr/bin/test
, bukan bawaan).1 Gunakan ini hanya jika
-executable
bendera darifind
tidak tersedia! ini sedikit berbeda dari-perm +111
solusi.sumber
'{}'
atau\{\}
.-executable
apakah atau seperti perintah saya.find . -type f -perm -u=x
ini tidak setara dengan-executable
:-executable
cocok dengan semua file yang pengguna dapat mengeksekusi, dan ini termasukg+x
jika saya berada di grup yang tepat atauo+x
. Sebenarnya-perm -u=x
akan menemukan banyak file yang tidak dapat dieksekusi oleh pengguna, dan melewatkan beberapa file yang dapat dieksekusi oleh pengguna. "{}
adalah kebutuhan hipotetis (dan mengutip tidak ada salahnya), dalam praktiknya itu tidak diperlukan dalam shell seperti POSIX dancsh
. Apakah Anda tahu kerang mana yang diperlukan?fish
,{}
memang harus di-escape sebagai salah satu'{}'
atau\{\}
. Perhatikan bahwabash
,,ksh
danzsh
berikan jenis ekspansi brace yang sama; Namun, mereka mencetak token tanpa tanda kutip{}
apa adanya (dan dengan demikian: tidak perlu melarikan diri), karena mereka TIDAK menganggapnya sebagai ekspresi kurung kurawal yang valid (mereka membutuhkan setidaknya 2 token, atau ekspresi urutan numerik yang valid), sedangkanfish
dianggap{}
sebagai kurung kurawal yang valid ekspresi yang menghasilkan string kosong .Anda bisa menggunakan
-executable
test flag:sumber
-rw-r-xr-x
yang-executable
tidak dapat dideteksiIni berhasil untuk saya & berpikir untuk berbagi ...
sumber
file
!find ./ -mime application/x-sharedlib -o -mime application/x-dosexec
tidak benar-benar menjamin bahwa file tersebut dapat dieksekusi, ia akan menemukan file dengan bit eksekusi yang ditetapkan. Jika kamu melakukan
pencarian di atas akan berpikir image.jpg adalah eksekusi bahkan jika itu benar-benar gambar jpeg dengan bit eksekusi set.
Saya biasanya mengatasi masalah ini dengan ini:
Jika Anda ingin menemukan untuk benar-benar mencetak informasi kubah tentang file yang dapat dieksekusi, Anda dapat melakukan sesuatu seperti ini:
Dalam contoh di atas nama path lengkap file ada di bidang terakhir dan harus mencerminkan di mana Anda mencarinya dengan awk "NAME = $ (awk '{print $ NF}' <<< $ LINE)" jika nama file ada di tempat lain di string keluaran find Anda perlu mengganti "NF" dengan posisi numerik yang benar. Jika pemisah Anda bukan spasi, Anda juga perlu memberi tahu awk apa pemisah Anda.
sumber
SANGAT konyol bahwa ini tidak super-mudah ... apalagi hampir mustahil . Angkat tangan, saya tunduk pada Apple / Spotlight ...
mdfind 'kMDItemContentType=public.unix-executable'
Setidaknya itu berhasil!
sumber
mdfind
OSX. Perhatikan bahwa perintah Anda melaporkan file executable Unix untuk seluruh sistem .mdfind -onlyin . 'kMDItemContentType=public.unix-executable'
membatasi hasil ke subpohon direktori saat ini. Tempat menarik kecil: membatasi pencarian ke direktori tertentu saja (tanpa subfolder) tampaknya tidak didukung. Symlink ke file yang dapat dieksekusi tampaknya tidak pernah disertakan. Anehnya, setelahmdfind
menemukan file yang dapat dieksekusi, kemudian menghapus bit yang dapat dieksekusi tidak diambil.mdfind -onlyin . 'kMDItemContentType=public.unix-executable'
berperilaku sepertifind . -type f -perm +111 -print
itu. Artinya, ia menemukan file dengan setiap bit set executable, yang dapat menghasilkan positif palsu (meskipun yang mungkin tidak menjadi masalah dalam praktek) - untuk benar-benar hanya menemukan file executable oleh pengguna saat menggunakan BSD menemukan, melihat jawaban @ gniourf_gniourf ini. Menggunakanfind
solusi berbasis memiliki keuntungan bahwa Anda dapat menemukan symlink ke file yang dapat dieksekusi juga, jika diinginkan (opsi-L
), yangmdfind
tampaknya tidak dapat dilakukan.ls /Applications/**/*(*)
dizsh
shellzsh
tip praktisnya - tidak tahu itu; (Tampaknya Anda dapat baik mencocokkan executable (*
) atau symlink (@
), tetapi tidak keduanya, kan?). Adapun poin awal Anda: Biarkan saya tegaskan:find . -type f -perm +a=x
akan melakukan apa yang dilakukanmdfind
perintah Anda, sambil memberikan lebih banyak fleksibilitas. Anda bahkan dapat memformulasi ulang agar sesuai dengan POSIX.Jawaban mudahnya adalah: "file yang dapat dieksekusi ada di direktori yang terdapat dalam variabel PATH" tetapi itu tidak akan benar-benar menemukan file yang dapat dieksekusi dan bisa saja kehilangan banyak file yang dapat dieksekusi.
Saya tidak tahu banyak tentang mac, tetapi saya pikir "mdfind 'kMDItemContentType = public.unix-executable'" mungkin melewatkan hal-hal seperti skrip yang diinterpretasikan
Jika tidak masalah bagi Anda untuk menemukan file dengan kumpulan bit yang dapat dieksekusi (terlepas dari apakah mereka benar-benar dapat dieksekusi) maka tidak masalah untuk melakukannya
jika didukung opsi "-executable" akan membuat filter lebih lanjut melihat acl dan artefak izin lainnya tetapi secara teknis tidak jauh berbeda dengan "-pemr +111".
Mungkin di masa mendatang find akan mendukung "-magic" dan membiarkan Anda mencari secara eksplisit file dengan id ajaib tertentu ... tetapi kemudian Anda harus menentukan untuk mendenda semua format yang dapat dieksekusi id ajaib.
Saya tidak mengetahui cara mudah yang benar secara teknis untuk unix.
sumber
Jadi jika Anda benar-benar ingin menemukan jenis file yang dapat dieksekusi (misalnya skrip, ELF binari dll .. dll ..) bukan hanya file dengan izin eksekusi maka Anda mungkin ingin melakukan sesuatu yang lebih seperti ini (di mana direktori saat ini. Dapat diganti dengan apapun direktori yang Anda inginkan):
Atau bagi Anda yang tidak menggunakan macports (pengguna linux) atau yang telah menginstal gnu menemukan yang Anda inginkan:
Meskipun jika Anda menggunakan OS X, ia hadir dengan utilitas kecil yang tersembunyi di suatu tempat bernama is_exec yang pada dasarnya menggabungkan tes kecil itu untuk Anda sehingga Anda dapat mempersingkat baris perintah jika Anda menemukannya. Tetapi cara ini lebih fleksibel karena Anda dapat dengan mudah mengganti tes == dengan tes = ~ dan menggunakannya untuk memeriksa properti yang lebih kompleks seperti file teks biasa yang dapat dieksekusi atau info lain apa pun yang dikembalikan oleh perintah file Anda.
Aturan pasti untuk kutipan di sini cukup buram, jadi saya akhirnya mengerjakannya dengan coba-coba tetapi saya ingin mendengar penjelasan yang benar.
sumber
Saya memiliki masalah yang sama, dan jawabannya ada di kode sumber dmenu : utilitas stest dibuat untuk tujuan itu. Anda dapat mengkompilasi file 'stest.c' dan 'arg.h' dan itu akan berfungsi. Ada halaman manual untuk penggunaan, yang saya taruh di sana untuk kenyamanan:
sumber