Domanda

Ho scritto uno script che prende, come argomento, una stringa che è una concatenazione di un nome utente e un progetto. Lo script dovrebbe passare (su) al nome utente, cd in una directory specifica in base alla stringa di progetto.

Io fondamentalmente voglio fare:

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

Il problema è che una volta che faccio un do ... semplicemente aspetta lì. Che ha senso in quanto il flusso di esecuzione è passata alla commutazione per l'utente. Una volta esco, poi il resto delle cose eseguire, ma non funziona, se lo desideri.

I anteposto su al comando svn, ma il comando non riuscito (vale a dire che non ha aggiornato svn nella directory desiderata).

Come faccio a scrivere uno script che permette all'utente di passare utente e richiamare svn (tra le altre cose)?

È stato utile?

Soluzione

Il trucco è quello di utilizzare il comando "sudo" al posto di "su"

Potrebbe essere necessario aggiungere questo

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

per file / etc / sudoers

e modificare lo script a:

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

Dove nomeutente2 è l'utente che si desidera eseguire il comando SVN, come e username1 è l'utente esegue lo script.

Se avete bisogno di più utenti di eseguire questo script, utilizzare un %groupname al posto del username1

Altri suggerimenti

Molto più semplice: l'uso sudo per eseguire una shell e utilizzare un heredoc per nutrire comanda.

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

( originariamente su SuperUser )

Utilizzare uno script come il seguente per eseguire il riposo o parte dello script in un altro utente:

#!/bin/sh

id

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

id

eof

È necessario eseguire tutti i comandi diversi utenti come proprio script. Se è solo uno, o alcuni comandi, quindi in linea dovrebbe funzionare. Se si tratta di un sacco di comandi, allora è probabilmente meglio per spostarli al proprio file.

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

Ecco un altro approccio, che era più conveniente nel mio caso (Volevo solo far cadere i privilegi di root e fare il resto del mio script da utente con accesso limitato): è possibile effettuare lo script di riavvio se stesso da utente corretto. Supponiamo che viene eseguito come root inizialmente. Poi sarà simile a questa:

#!/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"
...

Usa sudo invece

Modifica : Come Douglas ha sottolineato, non è possibile utilizzare cd in sudo in quanto non è un esterna comando. È necessario eseguire i comandi in una subshell per far funzionare il cd.

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

sudo -u $USERNAME -H cd ~/$PROJECT
sudo -u $USERNAME svn update

È possibile che venga chiesto di inserire tale password dell'utente, ma solo una volta.

Non è possibile cambiare utente all'interno di uno script di shell. Soluzioni alternative che utilizzano sudo descritto in altre risposte sono probabilmente la soluzione migliore.

Se siete abbastanza pazzi per eseguire script Perl come root, si può fare questo con le variabili che tengono $< $( $> $) reale / uid / gid effettivo, per esempio:.

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

Questo ha funzionato per me

ho diviso il mio "provisioning" dal mio "startup".

 # Configure everything else ready to run 
  config.vm.provision :shell, path: "provision.sh"
  config.vm.provision :shell, path: "start_env.sh", run: "always"

poi nella mia 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 &

ispira l'idea da @ MarSoft ma ho cambiato le linee come le seguenti:

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

Ho usato sudo per consentire una password meno l'esecuzione dello script. Se si vuole inserire una password per l'utente, rimuovere il sudo. Se non avete bisogno le variabili di ambiente, togliere -E da sudo.

Il /usr/bin/bash -l assicura che gli script profile.d vengono eseguiti per un ambiente inizializzata.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top