Pregunta

He escrito un guión que toma, como un argumento, una cadena que es una concatenación de un usuario y un proyecto. La secuencia de comandos se supone que el interruptor (Do) para el nombre de usuario, CD a un directorio específico basado en la cadena de proyecto.

Básicamente quiero hacer:

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

El problema es que una vez que hago un Do ... sólo espera allí. Lo cual tiene sentido ya que el flujo de ejecución ha pasado a cambiar al usuario. Una vez que la salida, entonces el resto de las cosas ejecutar pero no funciona como se desea.

I Do antepone al comando svn pero el mandato ha fallado (es decir que se desea no svn update en el directorio).

¿Cómo puedo escribir un script que permite al usuario cambiar de usuario e invocar SVN (entre otras cosas)?

¿Fue útil?

Solución

El truco consiste en utilizar el comando "sudo" en lugar de "su"

Es posible que deba agregar este

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

a su archivo / etc / sudoers

y cambiar la secuencia de comandos a:

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

Cuando nombredeusuario2 es que el usuario desea ejecutar el comando como SVN y nombredeusuario1 es el usuario que ejecuta la secuencia de comandos.

Si necesita múltiples usuarios para ejecutar este script, utilice un %groupname en lugar de la nombredeusuario1

Otros consejos

Mucho más simple: el uso sudo para ejecutar un shell y utilizar un heredoc para alimentarlo comandos.

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

( originalmente en superusuario )

El uso de un script como el siguiente para ejecutar el resto o parte de la secuencia de comandos en virtud de otro usuario:

#!/bin/sh

id

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

id

eof

Hay que realizar todos los comandos del usuario diferente como su propio guión. Si es sólo uno, o unos pocos comandos, a continuación, debería funcionar en línea. Si se trata de un montón de comandos, entonces es probablemente el mejor para moverlos a su propio archivo.

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

Aquí es otro enfoque, que era más conveniente en mi caso (solo quería soltar los privilegios de root y hacer el resto de mi script de usuario restringido): usted puede hacer que el script reiniciará de usuario correcto. Supongamos que se ejecuta como root inicialmente. A continuación, se vería así:

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

Uso sudo lugar

Editar : Como Douglas señaló, no se puede utilizar en cd sudo ya que no es un comando externo. Usted tiene que ejecutar los comandos en un subnivel para hacer el trabajo cd.

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

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

Se le puede pedir a la entrada que la contraseña del usuario, pero sólo una vez.

No es posible cambiar de usuario dentro de un script de shell. Soluciones provisionales utilizando sudo descrito en otras respuestas son probablemente su mejor apuesta.

Si estás loco suficiente para ejecutar los scripts de Perl como root, se puede hacer esto con las variables que mantienen $< $( $> $) reales efectivos / UID / GID, por ejemplo:.

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

Esto funcionó para mí

Me partió hacia fuera mi "aprovisionamiento" de mi "puesta en marcha".

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

A continuación, en mi 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 &

Inspirado por la idea de @ MarSoft pero he cambiado las líneas como la siguiente:

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

he utilizado sudo para permitir una contraseña con menos ejecución del script. Si desea introducir una contraseña para el usuario, eliminar el sudo. Si usted no necesita las variables de entorno, -E retirar del sudo.

Las asegura /usr/bin/bash -l, que los scripts se ejecutan profile.d para un entorno no inicializado.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top