Bagaimana saya dapat menemukan hanya file yang dapat dieksekusi di bawah direktori tertentu di Linux?

157

Bagaimana saya dapat menemukan hanya file yang dapat dieksekusi di bawah direktori tertentu di Linux?

HaiYuan Zhang
sumber
Berikut ini adalah jenis skrip BASH, tidak buruk adalah apa yang bisa saya katakan :) stackoverflow.com/a/20209457/2067125
AjayKumarBasuthkar
Bagaimana dengan menggunakan fileperintah standar ?
Terobosan
5
Bagi siapa pun yang ingin melakukan ini pada Mac (diuji pada OS X 10.9.5): ls -l | egrep '^[^d]..x..x..x.*$' Di atas akan mencantumkan semua executable (untuk semua / pengguna dan grup) di direktori saat ini. Catatan : -executableOpsi ini tidak berfungsi pada Mac karenanya solusi di atas.
techfoobar
1
@ techfoobar: Pertanyaannya tidak jelas: Apakah ini berarti file yang berisi kode yang dapat dieksekusi, atau apakah itu berarti file yang memiliki izin yang dapat dieksekusi? Tetapi bahkan jika kita berasumsi bahwa izin yang dapat dieksekusi adalah apa yang diinginkan (seperti mayoritas tanggapan tampaknya), pertanyaan itu tidak mengatakan yang dapat dieksekusi dunia . Solusi Anda akan menemukan file (dan juga fifos, soket, symlink, dll.) Yang memiliki izin eksekusi dunia, tetapi tidak 750 ( -rwxr-x---), yang masih dapat dieksekusi untuk beberapa pengguna.
G-Man

Jawaban:

157

Memeriksa file yang dapat dieksekusi dapat dilakukan dengan -perm(tidak disarankan) atau -executable(disarankan, karena ACL dimasukkan ke dalam akun). Untuk menggunakan -executableopsi:

find <dir> -executable

jika Anda ingin menemukan hanya file yang dapat dieksekusi dan direktori yang tidak dapat dicari, gabungkan dengan -type f:

find <dir> -executable -type f
rajutan
sumber
23
Shebang tidak berarti mereka dapat dieksekusi. itu hanya memberi tahu kita juru bahasa mana yang akan digunakan. dan menurut definisi linux “file executable” adalah file dengan executable (x) bit set
knittl
2
Versi find apa yang mendukung tipe itu untuk -type? man menemukan daftar b, c, d, p, f, l, s dan D pada sistem saya.
innaM
2
Sama di sini, temuan saya tidak memiliki -type xkeduanya.
davr
7
Jika Anda memiliki versi find lama (mungkin sebelum 4.3.8) yang kekurangan find -executable use find. -perm / u = x, g = x, o = x.
Ludwig Weinzierl
8
find: invalid predicate -executable'pada RHEL
SSH
33

Gunakan opsi temukan -perm. Ini akan menemukan file di direktori saat ini yang dapat dieksekusi oleh pemiliknya, oleh anggota grup atau oleh orang lain:

find . -perm /u=x,g=x,o=x

Sunting:

Saya baru saja menemukan opsi lain yang hadir setidaknya di GNU find 4.4.0:

find . -executable

Ini harus bekerja lebih baik karena ACL juga dipertimbangkan.

innaM
sumber
2
Ini hanya berfungsi pada versi find yang lebih baru. Yang datang secara default dengan CentOS memberikan kesalahan find: invalid mode / u = x, g = x, o = x'`
davr
12
Maka Anda harus mencoba versi "-perm +" yang sekarang tidak digunakan lagi di GNU find: find. -perma +111 "
innaM
Sepertinya -perm /111mungkin versi yang paling portabel.
Scott
12

Saya tahu pertanyaan yang secara spesifik menyebutkan Linux, tetapi karena ini adalah hasil pertama di Google, saya hanya ingin menambahkan jawaban yang saya cari (misalnya jika Anda - seperti saya saat ini - dipaksa oleh atasan Anda untuk menggunakan non GNU / Sistem Linux).

Diuji pada macOS 10.12.5

find . -perm +111 -type f
friederbluemle
sumber
1
Bekerja di RHEL 5 juga.
José Tomás Tocino
Ini adalah satu-satunya varian yang bisa saya gunakan pada OS X 10.14, thx
Justin
3

Saya memiliki pendekatan lain, jika Anda benar-benar hanya ingin melakukan sesuatu dengan file yang dapat dieksekusi - dan tidak harus benar-benar memaksa menemukan untuk memfilter sendiri:

for i in `find -type f`; do [ -x $i ] && echo "$i is executable"; done

Saya lebih suka ini karena tidak bergantung pada -executableplatform tertentu; dan itu tidak bergantung pada -permmana yang agak misterius, platform sedikit spesifik, dan seperti yang ditulis di atas membutuhkan file yang dapat dieksekusi untuk semua orang (bukan hanya Anda).

Ini -type fpenting karena dalam direktori * nix harus dapat dieksekusi agar dapat dilalui, dan semakin banyak kueri dalam findperintah, semakin efisien memori perintah Anda.

Bagaimanapun, hanya menawarkan pendekatan lain, karena * nix adalah tanah satu miliar pendekatan.

Mark McKenna
sumber
(0) Mana yang Anda sukai, misterius dan benar atau intuitif dan cacat? Saya lebih suka yang benar. (1)  jawaban innaM ini , menampilkan find -perm, menemukan file yang memiliki setiap mengeksekusi izin bit set. (2) Sebaliknya, jawaban ini hanya menemukan file yang izinnya dimiliki pengguna saat ini. Memang, itu mungkin yang diinginkan OP, tetapi tidak jelas. … (Lanjutan)
Scott
(Lanjutkan) ... (3) Untuk kejelasan, Anda mungkin ingin mengubah `…`ke $(…)- lihat ini , ini , dan ini . (4) Tapi jangan lakukan for i in $(find …); do …; gagal pada nama file yang mengandung spasi. Sebaliknya, lakukan find … -exec …. (5) Dan, ketika Anda bekerja dengan variabel shell, selalu kutip mereka (dalam tanda kutip ganda) kecuali Anda memiliki alasan yang baik untuk tidak melakukannya, dan Anda yakin Anda tahu apa yang Anda lakukan.
Scott
@scott OK, saya berdiri terkoreksi :) Saya membaca -permargumen yang membutuhkan ketiganya, bukan salah satunya. Juga, terima kasih atas masukan untuk melindungi argumen shell, itu saja yang tidak saya sadari.
Mark McKenna
@MarkMcKenna Anda memiliki salah ketik di sana: for i in temukan. -type f ; do [ -x $i ] && echo "$i is executable"; done; Anda kehilangan bagian <dir>, yang saya gunakan titik (.)
Devy
2

File yang ditandai executable tidak harus berupa file atau objek yang dapat dieksekusi atau dapat dimuat.

Inilah yang saya gunakan:

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
AjayKumarBasuthkar
sumber
2
Apa fungsinya?
DerMike
@DerMike, Ini adalah salah satu cara untuk menemukan executable di direktori saat ini, termasuk file .so, bahkan jika file tidak ditandai dapat dieksekusi.
AjayKumarBasuthkar
Nah, maksud saya, bagaimana cara melakukannya?
DerMike
Bunyinya dari header file untuk menemukan, setiap file biner atau file script memiliki header.
AjayKumarBasuthkar
Sejauh yang saya tahu, -name "*"tidak berpengaruh find- biasanya menemukan semua file yang tidak dihilangkan dengan tes.
G-Man
1

Sebagai penggemar ...

find /usr/bin -executable -type f -print0 | xargs file | grep ASCII

Menggunakan 'xargs' untuk mengambil output dari perintah find (menggunakan print0 untuk memastikan nama file dengan spasi ditangani dengan benar). Kami sekarang memiliki daftar file yang dapat dieksekusi dan kami menyediakannya, satu per satu, sebagai parameter untuk perintah 'file'. Kemudian ambil istilah ASCII untuk mengabaikan binari. Ganti -executable in find command dengan gaya apa yang Anda sukai (lihat jawaban sebelumnya) atau yang berfungsi pada 'NIX OS Anda

Saya meminta hal di atas untuk menemukan file dengan eval di skrip yang dimiliki oleh root, jadi buat yang berikut untuk membantu menemukan kelemahan eskalasi privat di mana pengguna root menjalankan skrip dengan parameter tidak aman ...

echo -n "+ Identifying script files owned by root that execute and have an eval in them..."
find /  -not \( -path /proc -prune \)  -type f -executable -user root -exec grep -l eval {} \; -exec file {} \; | grep ASCII| cut -d ':' -f1 > $outputDir"/root_owned_scripts_with_eval.out" 2>/dev/null &
Richard Braganza
sumber
Itu tidak akan berfungsi jika skrip berisi karakter non-ASCII. filemelaporkan penyandian, sehingga skrip python dapat dilaporkan sebagai a /usr/bin/python script, UTF-8 Unicode text executable. find ... | xargs file -b | grep -v '^ELF'bisa bekerja lebih baik untuk mengenali non-binari.
xenoid
0

Saya membuat fungsi di ~/.bashrcmalam ini untuk menemukan file yang dapat dieksekusi tidak di jalur sistem dan bukan direktori:

# Quickly locate executables not in the path
xlocate () {
    locate -0r "$1" | xargs -0 -I{} bash -c '[[ -x "$1" ]] && [[ ! -d "$1" ]] \
        &&  echo "executable: $1"'  _  {}
} # xlocate ()

Keuntungannya adalah ia akan mencari tiga distro Linux dan instalasi Windows di bawah satu detik di mana findperintahnya memakan waktu 15 menit.

Sebagai contoh:

$ time xlocate llocate
executable: /bin/ntfsfallocate
executable: /home/rick/restore/mnt/e/bin/llocate
executable: /mnt/clone/bin/ntfsfallocate
executable: /mnt/clone/home/rick/restore/mnt/e/bin/llocate
executable: /mnt/clone/usr/bin/fallocate
executable: /mnt/e/bin/llocate
executable: /mnt/old/bin/ntfsfallocate
executable: /mnt/old/usr/bin/fallocate
executable: /usr/bin/fallocate

real    0m0.504s
user    0m0.487s
sys     0m0.018s

Atau untuk seluruh direktori dan semua subs itu:

$ time xlocate /mnt/e/usr/local/bin/ | wc -l
65

real    0m0.741s
user    0m0.705s
sys     0m0.032s
WinEunuuchs2Unix
sumber