¿Cómo utilizo su para ejecutar el resto de la escritura del golpe como ese usuario?
-
22-09-2019 - |
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)?
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
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.