Wie stelle ich in einem Befehl "sudo find" sicher, dass der Befehl "-exec" als normaler Benutzer ausgeführt wird?

10

Ich versuche, den folgenden Befehl so process_pathsauszuführen , dass das Skript nicht mit erhöhten Rechten ausgeführt wird. Gibt es eine Möglichkeit, dies zu tun?

sudo find /path/ -exec process_paths '{}' \+

Hier /path/gibt es einige Dateien, die keine Leseberechtigung für normale Benutzer haben. Das Skript process_pathsbenötigt nur die Pfade.

pii_ke
quelle
... -exec sudo -u user process_paths {} \+
Satō Katsura
@SatoKatsura manchmal schlägt dies fehl mit sudo: unable to execute /usr/bin/perl: Argument list too long: /
pii_ke
1
Ja, siehe den Hinweis zur SUDO_COMMANDVariablen in find. . [^.] * -Typ f -print0 | xargs -0 sudo chmod 664; funktioniert nicht
Stéphane Chazelas
2
Wenn Sie die wollen -execBefehle als Benutzer aufgerufen werden, warum laufen Sie findmit sudoin erster Linie?
Marcelm
2
@marcelm Ich denke, der letzte Satz der Frage beantwortet deine.
Hey

Antworten:

16

Auf Systemen, die dies unterstützen (GNU und einige andere), können Sie Folgendes tun:

sudo find /path/ -print0 | xargs -r0 process_paths

xargswird nicht unter ausgeführt sudo, hat also immer noch die ursprünglichen Uids / Gids und auch die ursprüngliche Umgebung (im weiteren Sinne), nicht die von modifizierte sudo.

process_pathsstdin wird jedoch geändert (abhängig von der xargsImplementierung ist es offen für /dev/nulloder teilt das pipefrom sudo/ find.

Um zu verhindern , dass (mit GNU xargsund Muscheln wie ksh, zshoder bashdass die Unterstützung Prozess Substitution), könnten Sie tun:

xargs -r0a <(sudo find /path/ -print0) process_paths

Mit zsh:

sudo zsh -c '
   files=(/path/**/*(D))
   USERNAME=$SUDO_USER
   autoload zargs
   zargs $files -- process_paths'

In zsheinen Benutzernamen auf die Zuweisung von $USERNAMEspeziellen Variablen, setzt die uids, gids zu der des entsprechenden Benutzers in der Benutzerdatenbank wie sudo -u "$SUDO_USER"tun würde.

Du könntest es tun:

 sudo sh -c '
   exec find /path/ -exec sudo -u "$SUDO_USER" process_paths {} +'

Da sudojedoch eine $SUDO_COMMANDUmgebungsvariable (die die Verkettung der Argumente mit Leerzeichen enthält) an übergeben wird process_paths, wird die Liste der Dateien zweimal übergeben, process_pathswas bedeutet, dass die Grenze für die maximale Größe von args + env wahrscheinlich erreicht wird, wenn eine große vorhanden ist Anzahl der Dateien.

Bei den meisten suImplementierungen sollten Sie in der Lage sein:

 sudo sh -c '
   exec find /path/ -exec su "$SUDO_USER" -c '\''
     exec "$0" "$@"'\'' process_paths {} +'

obwohl da sunicht das gleiche Problem hat.

Stéphane Chazelas
quelle
1

Sie können verwenden sudo:

sudo find <directory> -exec sudo -u <normal_user> <command> {} \;

Aber wie in einem Kommentar gesagt, kann es anscheinend scheitern, wenn das {} für sudo zu lang ist.

Hallo
quelle