it-swarm.com.de

Wie verwende ich su, um den Rest des Bash-Skripts als dieser Benutzer auszuführen?

Ich habe ein Skript geschrieben, das als Argument eine Zeichenfolge verwendet, die aus einem Benutzernamen und einem Projekt besteht. Das Skript soll (su) auf den Benutzernamen wechseln, cd auf ein bestimmtes Verzeichnis basierend auf der Projektzeichenfolge.

Ich möchte im Grunde Folgendes tun:

su $USERNAME;  
cd /home/$USERNAME/$PROJECT;  
svn update;  

Das Problem ist, dass ich, sobald ich einen Su mache, nur dort warte. Dies ist sinnvoll, da der Ausführungsfluss auf den Benutzer übergegangen ist. Sobald ich beendet bin, werden die restlichen Dinge ausgeführt, aber es funktioniert nicht wie gewünscht.

Ich habe dem svn-Befehl su vorangestellt, aber der Befehl ist fehlgeschlagen (d. H. Er hat svn nicht im gewünschten Verzeichnis aktualisiert).

Wie schreibe ich ein Skript, mit dem der Benutzer den Benutzer wechseln und svn aufrufen kann (unter anderem)?

113
Avery

Der Trick besteht darin, den Befehl "Sudo" anstelle von "su" zu verwenden.

Möglicherweise müssen Sie dies hinzufügen

username1 ALL=(username2) NOPASSWD: /path/to/svn

in deine/etc/sudoers Datei

und ändere dein Skript in:

Sudo -u username2 -H sh -c "cd /home/$USERNAME/$PROJECT; svn update" 

Dabei ist Benutzername2 der Benutzer, unter dem Sie den SVN-Befehl ausführen möchten, und Benutzername1 der Benutzer, unter dem das Skript ausgeführt wird.

Wenn Sie mehrere Benutzer zum Ausführen dieses Skripts benötigen, verwenden Sie ein %groupname anstelle des Benutzernamens1

81
Kimvais

Viel einfacher: Verwenden Sie Sudo, um eine Shell auszuführen, und verwenden Sie heredoc , um sie mit Befehlen zu versorgen.

#!/usr/bin/env bash
whoami
Sudo -i -u someuser bash << EOF
echo "In"
whoami
EOF
echo "Out"
whoami

(Antwort rsprünglich auf SuperUser )

87
Dan Dascalescu

Verwenden Sie ein Skript wie das folgende, um den Rest oder einen Teil des Skripts unter einem anderen Benutzer auszuführen:

#!/bin/sh

id

exec Sudo -u transmission /bin/sh - << eof

id

eof
53
Walder

Sie müssen alle Benutzerbefehle als eigenes Skript ausführen. Wenn es sich nur um einen oder mehrere Befehle handelt, sollte Inline funktionieren. Wenn es sich um viele Befehle handelt, ist es wahrscheinlich am besten, sie in ihre eigene Datei zu verschieben.

su -c "cd /home/$USERNAME/$PROJECT ; svn update" -m "$USERNAME" 
43
Douglas Leeder

Hier ist noch ein weiterer Ansatz, der in meinem Fall praktischer war (ich wollte nur Root-Berechtigungen löschen und den Rest meines Skripts von einem eingeschränkten Benutzer ausführen): Sie können das Skript von einem korrekten Benutzer aus neu starten lassen. Nehmen wir an, es wird zunächst als root ausgeführt. Dann sieht es so aus:

#!/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" -- "[email protected]"
  # 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"
...
35
MarSoft

Verwenden Sie stattdessen Sudo

EDIT : Wie Douglas betonte, können Sie cd nicht in Sudo verwenden, da es kein externer Befehl. Sie müssen die Befehle in einer Subshell ausführen, damit cd funktioniert.

Sudo -u $USERNAME -H sh -c "cd ~/$PROJECT; svn update"
Sudo -u $USERNAME -H cd ~/$PROJECT
Sudo -u $USERNAME svn update

Möglicherweise werden Sie aufgefordert, das Kennwort des Benutzers einzugeben, jedoch nur einmal.

7
iamamac

Es ist nicht möglich, den Benutzer in einem Shell-Skript zu ändern. Problemumgehungen mit Sudo, die in anderen Antworten beschrieben wurden, sind wahrscheinlich die beste Wahl.

Wenn Sie verrückt genug sind, Perl-Skripte als root auszuführen, können Sie dies mit den Variablen $< $( $> $) tun, die die reale/effektive UID/GID enthalten, z.

#!/usr/bin/Perl -w
$user = shift;
if (!$<) {
    $> = getpwnam $user;
    $) = getgrnam $user;
} else {
    die 'must be root to change uid';
}
system('whoami');
6
P-Nuts

Das hat bei mir funktioniert

Ich habe mein "Provisioning" von meinem "Startup" getrennt.

 # 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 meiner 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 &
2
httpete