Wie verwende ich su den Rest der Bash-Skript als dieser Benutzer ausführen?
-
22-09-2019 - |
Frage
Ich habe ein Drehbuch geschrieben, die als Argument, eine Zeichenkette, die eine Verkettung von einem Benutzername und ein Projekt ist. Das Skript soll Schalter (su) mit dem Benutzernamen, cd in ein bestimmtes Verzeichnis auf der Grundlage der Projekt String.
Ich mag im Grunde tun:
su $USERNAME;
cd /home/$USERNAME/$PROJECT;
svn update;
Das Problem ist, dass wenn ich eine so tun ... es gibt nur wartet. Das macht Sinn, da der Ablauf der Ausführung der Umstellung auf den Benutzer weitergegeben hat. Sobald Ausgang I, dann der Rest der Dinge auszuführen, aber es funktioniert nicht wie gewünscht.
I vorangestellt su zum SVN-Befehl, aber der Befehl fehlgeschlagen ist (das heißt es nicht Aktualisierungs SVN im Verzeichnis gewünscht).
Wie schreibe ich ein Skript, das den Benutzer zu Benutzer wechseln und invoke svn ermöglicht (unter anderem)?
Lösung
Der Trick ist Befehl "sudo" anstelle von "su"
zu verwenden,können Sie benötigen diese
hinzufügenusername1 ALL=(username2) NOPASSWD: /path/to/svn
/ etc / sudoers-Datei
und Ihr Skript ändern:
sudo -u username2 -H sh -c "cd /home/$USERNAME/$PROJECT; svn update"
Wo username2 ist der Benutzer Sie den SVN-Befehl ausgeführt werden sollen, wie und username1 wird der Benutzer das Skript ausgeführt wird.
Wenn Sie mehrere Benutzer müssen dieses Skript ausführen, verwenden Sie einen %groupname
anstelle des username1
Andere Tipps
Viel einfacher: Verwendung sudo
eine Shell auszuführen und verwenden Sie einen heredoc es Befehle zu füttern.
#!/usr/bin/env bash
whoami
sudo -i -u someuser bash << EOF
echo "In"
whoami
EOF
echo "Out"
whoami
(Antwort ursprünglich auf Super-User-)
Verwenden Sie ein Skript wie die folgenden den Rest oder Teil des Skripts unter einem anderen Benutzer ausführen:
#!/bin/sh
id
exec sudo -u transmission /bin/sh - << eof
id
eof
Sie müssen alle die verschiedenen Benutzerbefehle als ihr eigenes Skript auszuführen. Wenn es nur eine ist, oder ein paar Befehle, dann sollten Inline arbeiten. Wenn es viele Befehle dann ist es wahrscheinlich am besten, sie zu ihrer eigenen Datei zu bewegen.
su -c "cd /home/$USERNAME/$PROJECT ; svn update" -m "$USERNAME"
Hier ist ein weiterer Ansatz, der in meinem Fall bequemer war (ich wollte nur root-Privilegien fallen zu lassen und den Rest meines Skript von eingeschränkten Benutzer tun): Sie das Skript neu starten, sich von der richtigen Benutzer machen. Nehmen wir an, es zunächst als root ausgeführt wird. Dann wird es wie folgt aussehen:
#!/bin/bash
if [ $UID -eq 0 ]; then
user=$1
dir=$2
shift 2 # if you need some other parameters
cd "$dir"
exec su "$user" "$0" -- "$@"
# nothing will be executed beyond that line,
# because exec replaces running process with the new one
fi
echo "This will be run from user $UID"
...
Verwenden sudo
statt
Bearbeiten : Wie Douglas wies darauf hin, können Sie nicht cd
in sudo
verwenden, da es nicht ein extern ist Befehl. Sie haben die Befehle in einer Subshell auszuführen, um die cd
Arbeit zu machen.
sudo -u $USERNAME -H sh -c "cd ~/$PROJECT; svn update"
sudo -u $USERNAME -H cd ~/$PROJECT
sudo -u $USERNAME svn update
Sie können zur Eingabe aufgefordert werden, das Kennwort des Benutzers, aber nur einmal.
Es ist nicht möglich, Benutzer innerhalb eines Shell-Skript zu ändern. Abhilfen sudo in anderen Antworten beschrieben sind wahrscheinlich die beste Wahl.
Wenn Sie verrückt genug Perl-Skripte als root ausführen, können Sie dies mit dem $< $( $> $)
Variablen, dem realen halten / uid / gid, z.
#!/usr/bin/perl -w
$user = shift;
if (!$<) {
$> = getpwnam $user;
$) = getgrnam $user;
} else {
die 'must be root to change uid';
}
system('whoami');
Das ist für mich gearbeitet
I aufzuschlüsseln meinen "Provisioning" von meiner "Inbetriebnahme".
# Configure everything else ready to run
config.vm.provision :shell, path: "provision.sh"
config.vm.provision :shell, path: "start_env.sh", run: "always"
dann in meinem start_env.sh
#!/usr/bin/env bash
echo "Starting Server Env"
#java -jar /usr/lib/node_modules/selenium-server-standalone-jar/jar/selenium-server-standalone-2.40.0.jar &
#(cd /vagrant_projects/myproj && sudo -u vagrant -H sh -c "nohup npm install 0<&- &>/dev/null &;bower install 0<&- &>/dev/null &")
cd /vagrant_projects/myproj
nohup grunt connect:server:keepalive 0<&- &>/dev/null &
nohup apimocker -c /vagrant_projects/myproj/mock_api_data/config.json 0<&- &>/dev/null &
Inspiriert durch die Idee von @ MarSoft aber ich änderte die Zeilen wie folgt aus:
USERNAME='desireduser'
COMMAND=$0
COMMANDARGS="$(printf " %q" "${@}")"
if [ $(whoami) != "$USERNAME" ]; then
exec sudo -E su $USERNAME -c "/usr/bin/bash -l $COMMAND $COMMANDARGS"
exit
fi
Ich habe sudo
verwendet ein Passwort weniger Ausführung des Skripts zu ermöglichen. Wenn Sie ein Passwort für den Benutzer eingeben möchten, entfernen Sie die sudo
. Wenn Sie die Umgebungsvariablen nicht benötigen, entfernen -E
von sudo.
Die /usr/bin/bash -l
stellt sicher, dass der profile.d
-Skripte für eine initialisierte Umgebung ausgeführt.