Führen Sie nur Teile eines Skripts als sudo aus und geben Sie das Kennwort nur einmal ein

14

Ich schreibe ein Skript (eigentlich eine Kombination aus Skripten und Makefile), das externe Abhängigkeiten installiert: einige apt-getBefehle, einige gitKlonen, Erstellen, Installieren, Hinzufügen von Benutzern zu Gruppen, ...

Einige der Vorgänge in diesen Skripten erfordern Superuser-Berechtigungen, andere nicht.

Bisher habe ich den gesamten make-Prozess mit sudo ausgeführt, aber er hat einige Nachteile:

  • gitrepos, die ich rootals Eigentümer bekomme , kann ich ohne sudooder nicht nachträglich ändernchown
  • Die Skripte, die Benutzer zu Gruppen hinzufügen, wissen nicht, welchen Benutzer sie hinzufügen sollen, da sie whoamizurückgegeben werdenroot

Was ist die beste Möglichkeit, als Superuser nur die Befehle auszuführen, die dies erfordern? Im Idealfall würde der Vorgang weiterhin die Eingabe meines sudoKennworts erfordern , jedoch nur einmal zu Beginn des Installationsvorgangs. Es würde es dann ganz am Ende vergessen, aber es die ganze Zeit bis dahin behalten (es kann mehrere Stunden dauern).

Die Lösungen, die ich online gefunden habe, umfassen:

  • sudo -vam anfang des skripts, aber wenn ich das richtig verstehe läuft das mal ab. Mein Skript könnte ein paar Stunden lang laufen
  • Ausführen des Skripts mit sudo, aber mit den Befehlen, die keinen Superuser benötigen sudo -u $(logname) <command>. Das ist, was ich jetzt mache, aber es fühlt sich so an, als sollte es umgekehrt sein.

Idealerweise möchte ich, dass mein Skript:

  1. Fragen Sie nach Superuser-Anmeldeinformationen
  2. Führen Sie normale Befehle als angemeldeter Benutzer aus
  3. Führen Sie sudo-Befehle mit den in Schritt 1 eingegebenen Anmeldeinformationen aus
  4. sudo -k um die Superuser-Sitzung zu schließen
Gauthier
quelle
2
Sie können weiterhin alles als sudo ausführen, und Ihr Skript kann die SUDO_USERUmgebungsvariable überprüfen . Falls vorhanden, enthält es den Benutzernamen des Benutzers, der sudo aufruft. So können Sie (als root) $ SUDO_USER: $ SUDO_GID $ your_files chown. Ebenso können Sie diese Variablen überprüfen, damit Ihre adduser-Befehle wissen, welcher Benutzer hinzugefügt werden soll.
Roadmr
... oder alles als root su $SUDO_USER -c commandausführen und für die Befehle als normaler Benutzer ausführen.
Rmano

Antworten:

7

Da Sie sudo-Zugriff haben, erstellen Sie eine sudoers-Datei für sich selbst und löschen Sie diese, wenn das Skript fertig ist:

# grant this user access to the sudo commands without passwords
# add all required cmds to the CMDS alias
sudo tee /etc/sudoers.d/$USER <<END
$USER $(hostname) = NOPASSWD: /usr/bin/apt-get, /usr/sbin/adduser, /bin/rm, ...
END

# your script goes here
sudo apt-get install ...
git clone ...
sudo adduser group2 $USER
sudo adduser group1 $USER
: ...

# then, remove the sudo access
sudo /bin/rm /etc/sudoers.d/$USER
sudo -k
Glenn Jackman
quelle
2

Eine Möglichkeit, dass ich nicht empfehlen generell, ist in dem Passwort selbst, und die Nutzung zu lesen sudo‚s -SOption , das Passwort zu übergeben , wie und bei Bedarf:

#! /bin/bash
IFS= read -rsp 'Enter your password: ' password
git clone ...
sudo -S apt-get install foo -y <<<"$password"

Von man sudo:

 -S, --stdin
             Write the prompt to the standard error and read the password
             from the standard input instead of using the terminal device.
             The password must be followed by a newline character.
muru
quelle
1
Ist das sicher? echo "$password"??
α 13sнιη
@KasiyA echo "$password"wäre nicht, aber Heredocs und Herestrings sind etwas sicherer. Sie sind in der Befehlszeile, die mit den üblichen Tools angezeigt wird, nicht sichtbar.
muru
1
Ich denke, genau genommen, echo "$password"auf der linke Seite eines Rohrs ist in einer Bash - Skript sicher. echoist eine eingebaute Shell; /bin/echoläuft nicht, wenn es so einfach heißt echo .... Einige andere Shells verfügen über eine integrierte echoFunktion ( dashz. B.), für Bourne-Shells ist jedoch keine erforderlich . Ich halte echo "$password" |das für akzeptabel, kann aber am besten vermieden werden, wenn jemand das Skript auf eine andere Shell portiert, ohne das Problem zu bemerken. Ich benutze ein nicht portierbares [[statt [in diesem Skript , um die gleiche Art von Problem abzuwenden. @KasiyA
Eliah Kagan