Użyj polecenia chmod wybiórczo

11

Chcę ustawić uprawnienia 755 na wszystkie pliki i podkatalogi w określonym katalogu, ale chcę uruchomić chmod 755 tylko dla tych komponentów, które nie mają uprawnień 755.

find /main_directory/ -exec chmod 755 {} \;

Jeśli findpolecenie zwróci długą listę, zajmie to dużo czasu. Wiem, że mogę użyć polecenia stat, aby sprawdzić uprawnienia na poziomie pliku ósemkowego dla każdego komponentu, a następnie użyć if-else, aby przełączyć uprawnienie do pliku, ale czy istnieje podejście z pojedynczą linią findi xargsnajpierw sprawdzić, jakie uprawnienia ma plik / katalog , a następnie użyj, chmodaby zmienić na 755, jeśli jest ustawiony na coś innego.

Kumarjit Ghosh
źródło
6
Może to być przedwczesna optymalizacja i może nawet nie być szybsza. Wykonanie wszystkich tych kontroli może spowolnić. Testowanie, aby upewnić się, że jest szybsze, zwróci się tylko, jeśli musisz to zrobić dużo.
ctrl-alt-delor
3
Prawdopodobnie nie chcesz udzielać uprawnień do wykonywania wszystkim plikom. To stworzy zagrożenie bezpieczeństwa. (jest to jeden z wektorów wirusów w systemie Microsoft Windows: wszystko jest wykonywalne). W trybie symbolicznym możesz powiedzieć u+rw,go+r,go-w,ugo+X- zwróć uwagę na stolicę.
ctrl-alt-delor
Zgadzam się z @ ctrl-alt-delor, ale sugerowałbym coś bliższego temu, o co prosiłeś, u = rwX, go = rX, który powinien osiągnąć to samo.
penguin359

Odpowiedzi:

21

Jeśli chcesz zmienić uprawnienia 755zarówno do plików, jak i katalogów, nie ma realnej korzyści z używania find(przynajmniej z punktu widzenia wydajności), a możesz po prostu to zrobić

chmod -R 755 /main_directory

Jeśli naprawdę chcesz użyć, findaby uniknąć zmiany uprawnień do rzeczy, które już mają 755uprawnienia (aby uniknąć aktualizacji ich sygnatury czasowej ctime), powinieneś również przetestować bieżące uprawnienia dla każdego katalogu i pliku:

find /main_directory ! -perm 0755 -exec chmod 755 {} +

-exec ... {} +Będzie zebrać jak wiele ścieżek, jak to możliwe, że przejdzie ! -perm 0755testu i wykonać chmodna nich wszystkich naraz.

Zwykle chciałoby się zmieniać uprawnienia do plików i katalogów osobno, aby nie wszystkie pliki były wykonywalne:

find /main_directory   -type d ! -perm 0755 -exec chmod 755 {} +
find /main_directory ! -type d ! -perm 0644 -exec chmod 644 {} +
Kusalananda
źródło
Działa jak urok, dziękuję. Pozdrawiam, Kumarjit
Kumarjit Ghosh
1
Podejrzewam, że używanie +zamiast ;robi tutaj dużą różnicę.
Kevin
Jest to szybki sposób - unikaj czeku. Chciałbym również użyć polecenia find, aby utworzyć listę tylko plików, do których zmiany masz uprawnienia, pozwoli to uniknąć błędów chmod w plikach, których nie można zmienić. <pre> <kod> # rwx, rw, wx, tylko znaleźć. -user $ (whoami) -perm / 002! -perm 0755 -exec chmod 0755 {} \; # znaleźć podział na dwie operacje. -user $ (whoami) -perm / 002! -perm 0755> /tmp/chfiles.txt dla pliku w $ (</ tmp / chfiles.txt) do chmod --quiet 0755 „$ {plik}” zrobione </code> </pre>
Chris Reid
@ChrisReid Pamiętaj, że zapętlanie listy takich ścieżek ulegnie awarii, jeśli jakakolwiek nazwa ścieżki zawiera znak spacji.
Kusalananda
Myślę, że musisz zmienić wewnętrzny separator pól (IFS) na „\ n” w skrypcie. Są to ustawienia środowiska, sposób, w jaki powłoka interpretuje je, zależy od wartości tych ustawień. Testuję skrypty na atrapach plików, zanim wykorzystam je do wyłapania błędnych destrukcji, takich jak zmiana nazw plików lub nadpisanie. Podoba mi się sposób drukowania powłoki ustawiony w IFS. IFS = $ (printf "\ n") # bardzo czytelny
Chris Reid
1

Jak findjuż otrzymałeś -exec ... +składnię, nie ma większego sensu w użyciu xargs, ale kiedy o nią prosisz:

find /main_directory -not -perm 0755 | xargs chmod 755
Henrik wspiera społeczność
źródło
1
Zauważ też, że xargs bez -0(w połączeniu z -print0in find; który jest rozszerzeniem GNU) może być dość problematyczny z punktu widzenia bezpieczeństwa, jeśli potencjalny atakujący może utworzyć nazwy plików zawierające białe spacje lub inne znaki specjalne. Lepiej więc trzymaj się, -execkiedy możesz
Matija Nalis
Nie ma potrzeby xargs(po prostu użyj -exec), a jeśli go użyjesz, powinieneś użyć -print0/ -0jak mówi Matija.
Kevin