Musisz naprawić uprawnienia do plików w katalogu osobistym użytkownika

24

Czy ktoś ma narzędzie lub skrypt, który rekurencyjnie poprawi uprawnienia do plików w katalogu?

Na maszynie z systemem Ubuntu Linux kilka plików zostało skopiowanych na dysk USB z pełnymi uprawnieniami 777 (użytkownik, grupa, inne - odczyt, zapis, wykonanie) w wyniku błędu. Chcę umieścić je z powrotem w poprawionym katalogu użytkownika.

Katalogi powinny mieć rozmiar 775, a wszystkie inne pliki mogą mieć rozmiar 664. Wszystkie pliki to obrazy, dokumenty lub pliki MP3, więc żaden z nich nie musi być wykonywalny. Jeśli bit katalogu jest ustawiony, wówczas wymaga wykonania, w przeciwnym razie potrzebuje tylko użytkownika i grupy, odczytu i zapisu.

Uznałem, że warto sprawdzić, czy takie narzędzie istnieje przed zhakowaniem skryptu powłoki :)

mlambie
źródło

Odpowiedzi:

51

To powinno załatwić sprawę:

find /home/user -type d -print0 | xargs -0 chmod 0775
find /home/user -type f -print0 | xargs -0 chmod 0664
freiheit
źródło
1
+1 za użycie opcji -print0 / xargs -0 :-).
sleske,
14

find może załatwić sprawę sam z opcją -exec:

find /home/user -type f -exec chmod 0664 {} \;
find /home/user -type d -exec chmod 0775 {} \;

aby uniemożliwić findowi pojawienie się chmod dla każdej pozycji:

find /home/user -type f -exec chmod 0664 {} +
find /home/user -type d -exec chmod 0775 {} +

(efektywnie wywołuje to chmod raz z listą wszystkich plików jako parametrów zamiast jednego chmod na plik)

ThorstenS
źródło
6
Wolniej niż przy użyciu xargs, ponieważ rozwidlasz chmod dla każdego pliku, gdzie xargs uruchomi proces chmod z tyloma plikami, ile zmieści się w linii poleceń. Na bardzo dużym drzewie może to mieć spore znaczenie.
David Pashley,
1
Ponadto print0 / xargs -0 obsłuży nawet bardzo dziwne nazwy plików; nie jestem pewien co do find -exec.
sleske,
8

Ta odpowiedź nie rozwiąże problemu, ale ktoś może uznać ją za przydatną w przypadku podobnego problemu, w którym pliki mają mniejsze uprawnienia niż powinny.

# chmod -R . u=rwX,g=rX,o=rX

Magią jest pozwolenie X, a nie x. Strona chmod opisuje to następująco:

wykonaj / wyszukaj tylko, jeśli plik jest katalogiem lub ma już uprawnienia do wykonywania dla niektórych użytkowników

Nie jest to odpowiednie w twoim przypadku, ponieważ twoje pliki mają uprawnienia do wykonywania, więc będą pasować do drugiego testu.

David Pashley
źródło
1
g powinno wynosić rwX dla 775 i 664.
awanturyn
1

Stworzyłem skrypt z rozwiązania freiheit, dodaje on podstawowe sprawdzanie argumentów.

#!/bin/sh

if [ $# -lt 1 ]; then
    echo "USAGE: $0 <path>"
    exit 1
fi

find $1 -type d -print0 | xargs -0 chmod 0755
find $1 -type f -print0 | xargs -0 chmod 0644
Marcs
źródło
Dobry pomysł. Jednak druga linia generuje błąd, gdy cel jest katalogiem: chmod: missing operand after ‘0644’. Czy mogę zasugerować zawinięcie instrukcji find ze sprawdzeniem, czy cel istnieje? if [ -d $1 ]; then find $1 -type d -print0 | xargs -0 chmod 0755; fi; if [ -f $1 ]; then find $1 -type f -print0 | xargs -0 chmod 0644; fi
Podkreślenie
To prawie poprawne; ale jeśli celem jest katalog, zapomniałeś chmod w nim zawartych plików, a jeśli jest to plik, wystarczy tylko chmod tylko tego pliku.
Sean
0

Jeśli używasz ssh, dobrze jest nie modyfikować ~/.sshuprawnień.

DIR=/home/user
find $DIR -type d -not -path "$DIR/.ssh" -print0 | xargs -0 chmod 0775
find $DIR -type f -not -path "$DIR/.ssh/*" -print0 | xargs -0 chmod 0664
Tombart
źródło
0

Pewnego dnia zrobiłem naprawdę prosty skrypt bashowy, ponieważ musiałem naprawić uprawnienia. Dlaczego nie ma formalnego narzędzia do resetowania uprawnień podstawowych, innych niż root, plików i folderów?

Skrypt używa find do 755 wszystkich folderów i bibliotek 644. Następnie testuje każdy plik za pomocą readelf, aby sprawdzić, czy ma binarny nagłówek elfa. Jeśli nie, skanuje pierwsze dwa znaki w poszukiwaniu szelangu #!. 755 tych instancji i 644 wszystko inne po sprawdzeniu, czy plik ma już odpowiednie uprawnienie.

Przypadki specjalne obsługiwane są z wyjątkiem, takim jak *.bakpliki do zignorowania.

#!/bin/bash
read -r -p "Correct file and folder permissions? [y/N] " chse
if [[ "$chse" =~ ^([yY][eE][sS]|[yY])+$ ]]; then
  echo "Processing ..."
  find -H $(pwd) -type d -exec chmod 0755 {} \;
  # set dirs to 755
  find -H $(pwd) -type f \( -iname '*.so.*' -o -iname '*.so' \) -exec chmod 0644 {} \;
  # libs
  IFS=$'\n'
  for value in $(find -H $(pwd) -type f ! \( -iname '*.so.*' -o -iname '*.so' -o -iname '*.bak' \) -printf '%p\n'); do
    tstbin=$(readelf -l "$value" 2>/dev/null | grep -Pio 'executable|shared')
    if [ -z "$tstbin" ]; then
      tstbat=$(cat "$value" | head -c2 | grep -io '#!')
      if [ -n "$tstbat" ]; then
        perm=$(stat -c '%a' "$value")
        if [ "$perm" != "755" ]; then
          chmod 755 $value
          echo "Set script  755 $value"
          # set batch to 755
        fi
      else
        perm=$(stat -c '%a' "$value")
        if [ "$perm" != "644" ]; then
          chmod 644 $value
          echo "Set regular 644 $value"
          # set regular files to 644
        fi
      fi
      # above aren't elf binary
    else
      perm=$(stat -c '%a' "$value")
      if [ "$perm" != "755" ]; then
        chmod 755 $value
        echo "Set binary  755 $value"
        # set elf binaries to 755
      fi
    fi
  done
  unset IFS
  # process linux permissions for files and folders
else
  echo "Aborted."
fi
noabody
źródło
0

Znalazłem uproszczone rozwiązanie powłoki C. To może nie być całkowicie głupi dowód, ale powinno działać w przypadku większości katalogów. Zakłada, że ​​uniksowe polecenie „file” działa, i znajduje pliki exec, aby zresetować je z powrotem do uprawnień exec:

find /home/user -type d | xargs chmod 0775
find /home/user -type f | xargs -0 chmod 0664
find /home/user -type f -exec file {} \; | grep executable | cut -d":" -f1 | xargs chmod 0775
K. Donovan
źródło
1
Nie tylko powtarza niektóre odpowiedzi, ale wprowadza błąd i funkcjonalność, o którą OP nie prosił.
RalfFriedl
0

Alternatywą, która nie odpowiada dokładnie pierwotnemu żądaniu, ale jest bardziej prawdopodobne, co zamierza OP, jest symboliczne określenie uprawnień. Na przykład zakładam, że OP chce „usunąć publiczny dostęp do zapisu i usunąć uprawnienia do wykonywania ze wszystkich plików”.

Jest to możliwe, jeśli używasz symbolicznej reprezentacji uprawnień.

  • ow to „usuń dostęp do zapisu z publicznego” („o” - inne, ”-” - usuń, „w” - zapis)
  • ax jest „usuń wykonaj dla wszystkich tylko na plikach” („a” - wszystko, - - ”- usuń,„ x ”- uruchom)

Zapisując go w ten sposób zamiast jawnie ustawiając „0664”, unikniesz przypadkowego zezwolenia na dodatkowe uprawnienia do plików, które zostały wcześniej zablokowane. Np. Jeśli plik miał numer 0770, to przez pomyłkę nie stanie się 0664.

Aby wykonać pierwszy wymóg, wystarczy użyć chmod:

chmod --recursive o-w $dir

Aby wykonać drugi warunek:

find $dir -type f -exec chmod a-x {} +

Lub zrobić oba:

find $dir -type f -exec chmod a-x,o-w {} +
find $dir -type d -exec chmod o-w {} +
chutz
źródło