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)?

War es hilfreich?

Lösung

Der Trick ist Befehl "sudo" anstelle von "su"

zu verwenden,

können Sie benötigen diese

hinzufügen
username1 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.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top