So überprüfen Sie die Gruppenberechtigungen einer Datei

9

Ich möchte die Gruppenberechtigungen einer Datei anhand eines Bash-Skripts überprüfen. Insbesondere muss ich überprüfen, ob für eine Datei das beschreibbare Gruppenbit aktiviert ist.

Das ist es. So einfach ist das. Jedoch:

  1. Ich brauche das auch, um tragbar zu sein.
  2. test -w <file Ich werde nicht sagen, ob die Gruppe beschreibbar ist.
  3. Die Ausgabe von ls -ldist gut für Menschen, aber nicht so sicher über Skripte. Technisch könnte ich die Ausgabe analysieren drwxrwxr-x, um die Gruppenbits zu extrahieren, aber das scheint spröde zu sein.
  4. Die Schnittstelle für statist zwischen OS X und anderen Systemen vollständig inkompatibel.
  5. find <file> -perm ... kann unmöglich die Antwort sein?
mislav
quelle
Müssen Sie das Gruppenberechtigungsbit überprüfen oder müssen Sie überprüfen, ob eine bestimmte Gruppe über Schreibberechtigungen verfügt? Die Gruppe (oder der Benutzer) kann über eine ACL Schreibberechtigung haben.
Gilles 'SO - hör auf böse zu sein'
Nur das Gruppenberechtigungsbit. Keine bestimmte Gruppe ist relevant.
Mislav

Antworten:

8

Methode 1 - stat

Sie können den statBefehl verwenden, um die Berechtigungsbits abzurufen. statist auf den meisten Unixen verfügbar (OSX, BSD, nicht AIX von dem, was ich finden kann). Dies sollte auf den meisten Unixen funktionieren, außer auf OSX & BSD, soweit ich das finde.

$ stat -c "%a" <file>

Beispiel

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

Verwenden Sie diesen Befehl:

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

Verwenden Sie eine einfache Methode, grepum festzustellen, ob der Gruppenberechtigungsmodus 6 oder 7 ist.

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

Für OS X und BSD müßten Sie diese Form verwenden stat, stat -f(oder vielleicht stat -x), und entsprechend zu analysieren. Da die Optionen statunterschiedlich sind, können Sie diesen Befehl in einen lsb_release -aBefehl einschließen und die entsprechende Version basierend auf dem Betriebssystem aufrufen. Nicht ideal, aber praktikabel. Erkenne , dass lsb_releaseist für Linux - Distributionen nur so eine weitere Alternative müssten für die Prüfung anderer Unix - Betriebssysteme entwickelt werden.

Methode 2 - finden

Ich denke, dieser Befehl könnte Ihnen jedoch besser dienen. Ich benutze findund den printfSchalter.

Beispiel

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

Methode 3 - Perl

Perl ist möglicherweise eine portablere Methode, um dies zu tun, abhängig von den Betriebssystemen, die Sie abdecken möchten.

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

HINWEIS: Im obigen Abschnitt wird die Perl- stat()Funktion zum Abfragen der Dateisystembits verwendet.

Sie können dies kompakter gestalten, indem Sie auf die Verwendung eines Arrays verzichten @pvund die Ausgabe von stat()direkt bearbeiten:

$ perl -le 'printf "%04o", (stat("a"))[2] & 07777;'
0664
slm
quelle
Ich denke, Sie haben seinen Punkt 4 verpasst. Der statBefehl variiert stark zwischen verschiedenen Systemen und ist nicht portabel.
Jordanm
@ Jordanm - danke, ich habe es gesehen, suchte nach einer Alternative. Ich denke, find . -printfkann es, kann aber nicht feststellen, ob es auf OSX 'find verfügbar ist.
slm
1
Ich konnte es auch nicht im POSIX2008-Handbuch finden, daher bin ich geneigt, dem zuzustimmen. Ich bin mir keiner anderen Methode sicher. Ich denke, Sie müssen hier in die Kugel beißen und herausfinden, welches Betriebssystem und den entsprechenden Anruf tätigen. Befehl, scheint der beste Ansatz zu sein.
slm
1
Ich konnte mir auch keine Methode vorstellen, die ein Standard-Shell-Dienstprogramm verwendet. Deshalb verwendet meine Antwort Perl.
Jordanm
1
@ Jordanm - tolle Köpfe. Ich habe auch an einer Perl-Lösung gearbeitet 8-)
slm
1

Eine Option ist die Verwendung perl, die überall tragbar sein perlwird. Es ist schwierig, ein Unix-System ohne es zu finden. Hier ist ein Beispiel, wie es in ein Shell-Skript integriert werden kann:

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

Ähnliche perlBeispiele finden Sie im stat perldoc .

Jordanm
quelle
1

lsAm Ende habe ich analysiert:

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

Ich bin dankbar für die ausführliche Antwort von @ slm, aber keine der anderen Methoden ist so einfach. Die statMethode würde erfordern, dass ich mindestens zwei verschiedene Aufrufe schreibe, um OS X abzudecken, und selbst danach gibt sie die oktale Darstellung zurück, auf die ich noch arithmetisch anwenden muss. Die Perl-Methode ist in Ordnung, erfordert jedoch, dass ich einen Interpreter für eine so einfache Aufgabe starte, und ich möchte sie einfach halten und nur Posix-Utils verwenden.

mislav
quelle
2
Sie verwenden Bash, nicht nur POSIX. In POSIX:perms=$(ls -ld -- "$1"); perms=${perms%% *}; case $perms in ?????w????) …
Gilles 'SO - hör auf böse zu sein'
0
FILE="filename";G=$(stat -c '%a' ${FILE} | cut -c2);
if [ $G -gt 5 ];then   echo "Group write is set on ${FILE}";fi

Alle Standard-Unix / Linux-Tools.

Ich nehme an, es ist MÖGLICH, Gruppen schreiben zu lassen, aber nicht Gruppen lesen. In dieser Möglichkeit wäre es entweder eine case-Anweisung 2 | 3 | 6 | 7) oder ein grep '[2 | 3 | 6 | 7]'

Doc
quelle