
Ich versuche ein Bash-Skript zu schreiben, das
- Kontextwechsel zu einem anderen Benutzer (in diesem Fall root)
- führt eine Reihe von Befehlen aus, umich.Erstellen Sie einen Benutzer (interaktiver Aufrufer mit der Aufforderung zur Eingabe des Benutzernamens) undii.legt das Passwort für diesen Benutzer fest
- erhält einen Rückgabewert
- dann macht er weiter mit dem Rückgabewert
Ich habe bisher eine << EOF-Eingabe (Abb.1), eine Funktion (Abb.2) und das Abrufen/Ausführen eines separaten Skripts (Abb. 3). Ich habe jedoch nicht die gewünschten Ergebnisse erzielt.
sudo su - << 'EOF'
# do stuff...
EOF
Abb.1
function myfunc()
{
local myresult='some value'
echo "$myresult"
}
Abb.2
sudo su - -c bash <(curl -fksSL https://<my-script-location>.sh)
Abb. 3
Antwort1
sudo su - << 'EOF' # do stuff... EOF
Dies funktioniert, allerdings mit einer Einschränkung: Das Skript wird über die Standardeingabe an die Shell übergeben, sodass Sie die Standardeingabe nicht für andere Zwecke verwenden können, beispielsweise zum Lesen des Namens des zu erstellenden Benutzers.
Die einfache Möglichkeit, die Standardeingabe beizubehalten, besteht darin, stattdessen den Shell-Befehl als Argument zu übergeben.
Beachten Sie, dass dies sudo su
redundant ist – führt den angegebenen Befehl als Root aus, und das ist auch sudo
der einzige Zweck von . Verwenden Sie anstelle von , wenn Sie eine Login-Shell als Root ausführen möchten – was hier wahrscheinlich unnötig ist – oder um einfach eine Shell als Root auszuführen.su
sudo -i
sudo su -
sudo sh
sudo sh -c '
# do stuff...
'
Dies macht es umständlich, ein einfaches Anführungszeichen im Shell-Snippet zu verwenden. Sie können verwenden, '\''
um ein einfaches Anführungszeichen innerhalb des in einfache Anführungszeichen gesetzten Literals zu setzen. Wenn Sie die Struktur des Here-Dokuments beibehalten möchten, gibt es mehrere Möglichkeiten. Am einfachsten ist es, das Here-Dokument zu übergeben.auf einem anderen Deskriptor. Dafür muss die closefrom_override
Option allerdings in der Sudo-Konfiguration aktiviert sein, was standardmäßig nicht der Fall ist; standardmäßig sudo
werden alle Datei-Deskriptoren außer stdin, stdout und stderr geschlossen.
sudo -C 3 sh -c '. /dev/fd/3' 3<<'EOF'
# do stuff...
EOF
Wenn Sie möchten, dass Ihr Code auf Maschinen portierbar ist, auf denen diese Option nicht aktiviert ist, können Sie das Skript aus einem Heredoc lesen und es als Argument an die Shell übergeben.
script=$(cat <<'EOF'
# do stuff...
EOF
)
sudo sh -c "$script"
Wenn Sie möchten, dass das sudo-Skript vom Terminal lesen kann, können Sie den Skripttext alternativ über die Standardeingabe übergeben. Eine Einschränkung dieses Ansatzes besteht darin, dass die Eingabe des gesamten Skripts nicht umgeleitet werden kann.
sudo sh <<'EOF'
exec </dev/tty
# do stuff...
EOF
Antwort2
Vorausgesetzt, der aufrufende Benutzer sudo
kann Folgendes zuordnen tty
:
Defaults someuser:requiretty
ans wurden die Berechtigungen erteilt, die erforderlichen Befehle als Root auszuführen:
Cmnd_Alias STUFF = /usr/bin/passwd, /usr/sbin/useradd
someuser ALL = STUFF
Ein Skript, das sudo
Aufrufe enthält, wird interaktiv sein. Sie können den Benutzernamen als Positionsargument übergeben:
sudo useradd $1
sudo passwd $1
und prüfen Sie wie gewohnt den Retourenstatus mit $?
.
Antwort3
su -c '. /dev/fd/4' 4<<\SCRIPT
...automated stuff here...
....then for interactive...
exec </dev/tty
SCRIPT
Sollte funktionieren. Passen Sie es Ihren Bedürfnissen entsprechend an – es wird jedoch den Kontext wechseln und der Rückgabestatus der Shell wird angezeigt, $?
wenn Sie damit fertig sind.