Cara menghapus bit yang dapat dieksekusi secara rekursif dari file (bukan direktori)

73

Ketika saya mencolokkan USB stick (FAT) ke mesin Mac atau Ubuntu saya, semua file memiliki bit executable yang ditetapkan. Setelah menyalin struktur direktori ke hard disk saya bagaimana cara menghapus bit yang dapat dieksekusi secara rekursif hanya dari file dan menyimpannya di direktori?

Mike L.
sumber

Jawaban:

133

Dengan chmodvarian perintah tunggal GNU (di Ubuntu) (dimulai dari direktori saat ini):

chmod -R -x+X .

Penjelasan:

  • -R - beroperasi secara rekursif
  • -x - hapus flag yang dapat dieksekusi untuk semua pengguna
  • +X - mengatur flag yang dapat dieksekusi untuk semua pengguna jika itu adalah direktori

Dalam hal ini, modal Xhanya berlaku untuk direktori karena semua flag yang dapat dieksekusi dibersihkan oleh -x. Jika tidak, +Xset flag yang dapat dieksekusi juga jika flag tersebut awalnya ditetapkan untuk pengguna, grup, atau orang lain.

Dengan BSD chmod(yang ada pada Mac OS X) Anda harus melakukannya secara terpisah dalam dua perintah:

sudo chmod -R -x * && sudo chmod -R +X *

(Jika Anda ingin memasukkan file tersembunyi di direktori utama juga, Anda mungkin perlu mengubah * ke. (Titik), tetapi tidak teruji.)

pabouk
sumber
1
Pada Ubuntu 13.04 diperlukan sedikit penyesuaian:chmod -R a-x+X *
Eero Aaltonen
@EeroAaltonen: Terima kasih atas catatannya. Ini bisa terjadi jika Anda umasktidak mengizinkan xizin untuk semua. Apakah Anda menggunakan default umaskatau Anda mengubahnya? Bisakah Anda mengirim output dari umaskperintah? Selain solusi Anda, ada juga kemungkinan ini: chmod -R a-x,+X *yang akan mengatur xizin menurut Anda umask. Saya akan memperbarui jawabannya tetapi saya ingin memeriksa perilaku di BSD / Mac OS X terlebih dahulu.
pabouk
@pabouk oopsie! Itu sebenarnya kotak CentOs di mana saya telah menetapkan umask saya ke 0007.
Eero Aaltonen
Ini hanya sedih ... :( Saya suka findvarian dalam jawaban di bawah untuk gaya menggabungkan alat sederhana yang melakukan One Thing Well.
mikezter
2
Gunakan .alih-alih *jika Anda ingin ini diterapkan ke semua file
John Magnolia
46

Jika Anda masuk ke jalur yang benar terlebih dahulu:

find . -type f -exec chmod -x {} \;

atau

chmod -x $(find . -type f)

Temuan ini menemukan semua file tipe 'f' (yang berarti file biasa) di path. dan kemudian memanggil chmod -x pada setiap file. {} Akan diganti untuk nama file dan \; mengakhiri perintah chmod.

Matthijs P
sumber
6
Jika Anda findmendukungnya, gunakan -exec ... \+sebagai ganti -exec ... \;- itu akan membutuhkan lebih sedikit fork+ execs. Jika tidak, gunakan find ... -print0 | xargs -0 ....
ephemient
5
Saya telah menggunakan teknik ini, tetapi dengan "-perm +111" ditambahkan ke dalam penemuan sehingga hanya chmod yang memiliki set x-bit:find . -type f -perm +111 -exec chmod -x {} \;
chrish
4
+1 @Matthijs Alasan mengapa ini lebih baik daripada solusi pabouk adalah bahwa perintah ini meninggalkan direktori sendirian, sementara pabouk mengatur ulang bit yang dapat dieksekusi di semua direktori. Mungkin ada beberapa direktori yang bit eksekusinya tidak diset, dan perintah pabouk menyetelnya, sementara orang mungkin ingin membiarkannya apa adanya.
MariusMatutiae
pendekatan ke-2 akan gagal untuk jalur yang berisi spasi.
MestreLion
@ephemient: jika finddukungan Anda, -print0saya cukup yakin itu juga akan mendukung-exec
MestreLion
3

Di bawah Linux dan Unix di jendela terminal atau Di Mac OS X, gunakan ini di Terminal.app:

find . -type f -print0 | xargs -0 chmod -x
pengguna227317
sumber
1
Ini, pada dasarnya, tidak berbeda dari jawaban Matthijs P dari 2011.
slhck
Bisakah Anda mengingat baris perintah ini? Saya tidak bisa.
Mike L.
Lihat komentar ephemient di bawah jawaban Matthijs untuk melihat mengapa jawaban ini bermanfaat.
PatrickT
2

The chmod -x+Xcara tidak bekerja untuk saya di ubuntu baik, sehingga saya menulis skrip python minimal ini:

#!/usr/bin/python3
import os
for par, dirs, files in os.walk('.'):
    for d in dirs:
        os.chmod(par + '/' + d, 0o755)
    for f in files:
        os.chmod(par + '/' + f, 0o644)

Jika mungkin ada hal-hal tambahan mewah seperti soket di sistem file Anda, Anda mungkin ingin mengelilingi chmod terakhir dengan mencoba / menangkap.

mic_e
sumber