Jak sprawdzić uprawnienia grupy do pliku

9

Chciałbym sprawdzić uprawnienia grupy do pliku ze skryptu bash. W szczególności muszę sprawdzić, czy plik ma zapisany bit grupy.

Otóż ​​to. Proste. Jednak:

  1. Potrzebuję również tego, aby był przenośny.
  2. test -w <file nie powie mi, czy można to zapisać w grupie.
  3. Dane wyjściowe ls -ldsą dobre dla ludzi, ale nie tak pewne co do skryptów. Technicznie mógłbym przeanalizować dane wyjściowe, na przykład w drwxrwxr-xcelu wyodrębnienia bitów grupy, ale wydaje się to kruche.
  4. Interfejs dla statjest całkowicie niekompatybilny między OS X a innymi systemami.
  5. find <file> -perm ... nie może być odpowiedź?
mislav
źródło
Czy musisz sprawdzić bit uprawnień grupy, czy musisz sprawdzić, czy konkretna grupa ma uprawnienia do zapisu? Grupa (lub użytkownik) może mieć uprawnienia do zapisu za pośrednictwem listy ACL.
Gilles „SO- przestań być zły”
Tylko bit uprawnień grupy. Żadna konkretna grupa nie jest istotna.
mislav

Odpowiedzi:

8

Metoda nr 1 - stat

Możesz użyć statpolecenia, aby uzyskać bity uprawnień. statjest dostępny na większości Uniksów (OSX, BSD, a nie AIX z tego, co mogę znaleźć). To powinno działać na większości Uniksów, z wyjątkiem OSX i BSD z tego, co mogę znaleźć.

$ stat -c "%a" <file>

Przykład

$ ls -l a
-rw-rw-r-- 1 saml saml 155 Oct  6 14:16 afile.txt

Użyj tego polecenia:

$ stat -c "%a" afile.txt
664

I użyj prostego, grepaby sprawdzić, czy tryb uprawnień dla grup to 6 czy 7.

$ stat -c "%a" afile.txt | grep ".[67]."

Dla OSX i BSD trzeba by skorzystać z tej formy stat, stat -f(albo stat -x) i analizować odpowiednio. Ponieważ opcje statsą różne, możesz zawinąć to polecenie w lsb_release -apolecenie i wywołać odpowiednią wersję na podstawie systemu operacyjnego. Nie idealny, ale wykonalny. Zdaj sobie sprawę, że lsb_releasejest to dostępne tylko dla dystrybucji Linuksa, więc należałoby opracować inną alternatywę do testowania innych systemów uniksowych.

Metoda nr 2 - znajdź

Myślę, że to polecenie może ci lepiej służyć. I sprawia, że wykorzystanie findi printfprzełącznik.

Przykład

$ find a -prune -printf '%m\n'
664

Metoda nr 3 - Perl

Perl może być bardziej przenośnym sposobem na zrobienie tego w zależności od systemów operacyjnych, które próbujesz zainstalować.

$ perl -le '@pv=stat("afile.txt"); printf "%04o", $pv[2] & 07777;'
0664

UWAGA: Powyższe wykorzystuje stat()funkcję Perla do zapytania bitów systemu plików.

Możesz uczynić to bardziej kompaktowym, rezygnując z używania tablicy @pvi zajmując się wynikami stat():

$ perl -le 'printf "%04o", (stat("a"))[2] & 07777;'
0664
slm
źródło
Myślę, że przegapiłeś jego punkt 4. statPolecenie różni się w zależności od systemu i nie jest przenośne.
jordanm
@jordanm - dzięki, że to widziałem, szukałem alternatywy. Myślę, że find . -printfmogę to zrobić, ale nie mogę ustalić, czy jest dostępne w znalezieniu OSX.
slm
1
Nie mogłem też znaleźć tego w podręczniku POSIX2008, więc jestem skłonny się zgodzić. Nie jestem pewien innych metod. Myślę, że musisz ugryźć pocisk tutaj i wykryć, który system operacyjny i wywołać odpowiedni. wydaje się najlepszym podejściem.
slm
1
Nie mogłem też wymyślić metody wykorzystującej standardowe narzędzie powłoki. Dlatego moja odpowiedź używa perla.
jordanm
1
@jordanm - wielkie umysły. Pracowałem też nad rozwiązaniem perlowym 8-)
slm
1

Jedną z opcji jest użycie perl, które będzie przenośne wszędzie, gdzie perljest dostępna. Bez niego trudno jest znaleźć system uniksowy. Oto przykład, w jaki sposób można go zintegrować ze skryptem powłoki:

if perl -e 'use Fcntl ":mode"; exit( ((stat("file.txt"))[2] & S_IWGRP) >> 3)'; then
    echo "file is group writable"
else
    echo "file is not group witeable"
fi

Podobne perlprzykłady można znaleźć w stat perldoc .

Jordan
źródło
1

Skończyło się na lsanalizie:

is_group_writable() {
  local ls="$(ls -ld "$1")"
  [ "${ls:5:1}" = "w" ]
}

Jestem wdzięczny za obszerną odpowiedź @ slm, ale żadna z pozostałych metod nie jest tak prosta. statMetoda wymagałaby mi napisać co najmniej dwa różne wywołania na pokrycie OS X, a nawet po tym zwraca reprezentację ósemkowej które wciąż muszą stosować się do arytmetyki. Metoda Perla jest OK, ale wymaga ode mnie uruchomienia interpretera dla tak prostego zadania, i chciałbym, aby była prosta i używała tylko narzędzi POSIX.

mislav
źródło
2
Używasz bash, a nie tylko POSIX. W POSIX:perms=$(ls -ld -- "$1"); perms=${perms%% *}; case $perms in ?????w????) …
Gilles 'SO- przestań być zły'
0
FILE="filename";G=$(stat -c '%a' ${FILE} | cut -c2);
if [ $G -gt 5 ];then   echo "Group write is set on ${FILE}";fi

Wszystkie standardowe narzędzia Unix / Linux.

Przypuszczam, że MOŻLIWE jest zapisywanie grupowe, ale nie odczytywanie grupowe. W takiej możliwości byłoby to albo oświadczenie o sprawie 2 | 3 | 6 | 7), albo grep „[2 | 3 | 6 | 7]”

Doc
źródło