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 GNU find
tersedia.
- GNU
find
hadir dengan sebagian besar distro
Linux
- Sebaliknya, platform berbasis BSD, termasuk macOS, hadir dengan BSD find, yang kurang kuat.
- Karena tuntutan skenario,
-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).
- Menggunakan hanya
-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 POSIXfind
, 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 (gunakan find -L
untuk 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 exec
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) :
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
-perm
primer (dikenal sebagai tes dalam terminologi menemukan GNU).
-perm
memungkinkan 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 x
dapat dieksekusi, misalnya, dan ditetapkan ke kepala sekolah menggunakan operator =
, +
dan -
; untuk diskusi lengkap, termasuk mode oktal, lihat spesifikasi POSIX untuk chmod
utilitas 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
)
-o
untuk 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=x
setara dengan -u+x
- kecuali jika Anda menerapkannya -x
nanti, tetapi tidak ada gunanya melakukan itu).
- Gunakan
,
untuk bergabung dengan mode parsial; DAN logika tersirat; misalnya, -u=x,g=x
berarti 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
-perm
ekspresi 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), -o
dan 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
-L
menginstruksikan find untuk mengevaluasi target symlink daripada symlink itu sendiri; oleh karena itu, tanpa -L
, -type f
akan 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 -executable
sejak man find
GNU 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.