sudo su -
, eine komplizierte Schreibweise sudo -i
, schafft eine makellose Umgebung. Das ist der Punkt einer Login-Shell. Sogar eine Ebene sudo
entfernt die meisten Variablen aus der Umgebung. Weiterhin sudo
ist ein externer Befehl; Es gibt keine Möglichkeit, Berechtigungen im Shell-Skript selbst zu erhöhen, sondern nur ein externes Programm ( sudo
) mit zusätzlichen Berechtigungen auszuführen. Dies bedeutet, dass in der übergeordneten Shell definierte Shell-Variablen (dh nicht exportierte Variablen) und Funktionen nicht verfügbar sind die Kinderhülle.
Sie können Umgebungsvariablen weitergeben, indem Sie keine Anmeldeshell ( sudo bash
anstelle von sudo su -
oder sudo -i
) aufrufen und sudo so konfigurieren, dass diese Variablen (mit Defaults !env_reset
oder Defaults env_keep=…
in der sudoers
Datei) durchgelassen werden. Dies hilft Ihnen bei Funktionen nicht weiter (obwohl bash über eine Funktion zum Exportieren von Funktionen verfügt, blockiert sudo diese).
Der normale Weg, um Ihre Funktionen in die untergeordnete Shell zu bekommen, besteht darin, sie dort zu definieren. Achten Sie <<EOF
auf das Zitieren: Wenn Sie für das Here-Dokument verwenden, wird der Inhalt des Here-Dokuments zuerst von der übergeordneten Shell erweitert, und das Ergebnis dieser Erweiterung wird zum Skript, das die untergeordnete Shell sieht. Das heißt, wenn Sie schreiben
sudo -u "$target_user" -i <<EOF
echo "$(whoami)"
EOF
Dies zeigt den Namen des ursprünglichen Benutzers an, nicht des Zielbenutzers. Um diese erste Phase der Erweiterung zu vermeiden, zitieren Sie die hier angegebene Dokumentmarkierung nach dem <<
Operator:
sudo -u "$target_user" -i <<'EOF'
echo "$(whoami)"
EOF
Wenn Sie also keine Daten von der übergeordneten Shell an die untergeordnete Shell übergeben müssen, können Sie ein hier zitiertes Dokument verwenden:
#!/bin/bash
sudo -u "$target_user" -i <<'EOF'
log_f() {
echo "LOG line: $@"
}
intVAR=$(date)
log_f "${intVAR}"
EOF
Während Sie eine hier nicht zitierte Dokumentmarkierung verwenden können, um Daten von der übergeordneten Shell an die untergeordnete Shell zu übergeben, funktioniert dies nur, wenn die Daten kein Sonderzeichen enthalten. Das liegt daran, dass in einem Skript wie
sudo -u "$target_user" -i <<EOF
echo "$(whoami)"
EOF
Die Ausgabe von whoami
wird zu einem Bit Shell-Code, nicht zu einer Zeichenfolge. Wenn der whoami
Befehl beispielsweise zurückgegeben "; rm -rf /; "true
wird, führt die untergeordnete Shell den Befehl aus echo ""; rm -rf /; "true"
.
Wenn Sie Daten von der übergeordneten Shell übergeben müssen, können Sie sie auf einfache Weise als Argumente übergeben. Rufen Sie die untergeordnete Shell explizit auf und übergeben Sie die Positionsparameter:
#!/bin/bash
extVAR="yourName"
sudo -u "$target_user" -i sh _ "$extVAR" <<'EOF'
log_f() {
echo "LOG line: $@"
}
intVAR=$(date)
log_f "${intVAR}" "${1}"
EOF
Wenn Sie mehrere Variablen übergeben müssen, ist es besser, sie nach Namen zu übergeben. Rufen Sie env
explizit auf, um Umgebungsvariablen für die untergeordnete Shell festzulegen.
#!/bin/bash
extVAR="yourName"
sudo -u "$target_user" -i env extVAR="$extVAR" sh <<'EOF'
log_f() {
echo "LOG line: $@"
}
intVAR=$(date)
log_f "${intVAR}" "${1}"
EOF
Beachten Sie, dass Sie, wenn Sie erwartet haben /etc/profile
und der Zielbenutzer ~/.profile
gelesen werden soll, diese explizit lesen oder bash --login
stattdessen aufrufen müssen sh
.