He escrito un script que toma, como argumento, una cadena que es una concatenación de un nombre de usuario y un proyecto. Se supone que el script cambia (su) al nombre de usuario, cd a un directorio específico basado en la cadena del proyecto.
Básicamente quiero hacer:
su $USERNAME;
cd /home/$USERNAME/$PROJECT;
svn update;
El problema es que una vez que hago un su ... solo espera allí. Lo cual tiene sentido ya que el flujo de ejecución ha pasado a cambiar al usuario. Una vez que salgo, el resto de las cosas se ejecutan pero no funciona como se desea.
Prepuse su al comando svn pero el comando falló (es decir, no actualizó svn en el directorio deseado).
¿Cómo escribo un script que permita al usuario cambiar de usuario e invocar svn (entre otras cosas)?
fuente
chsh
para los otros usuarios. Mi problema se enumera aquí en stackoverflow.com/q/15307289/80353 ¿Cómo adapto su respuesta en mi situación?sudo
osu
es de importancia secundaria,sudo
es mucho más seguro y conveniente.Mucho más simple: use
sudo
para ejecutar un shell y use un heredoc para alimentar sus comandos.(respuesta original en SuperUser )
fuente
-i
para obtenersomeuser
el entorno esperado.sudo
puede ser conveniente, pero no es bueno si no está listo para usar (como en AIX).su -c 'commands'
Es la respuesta correcta.Use un script como el siguiente para ejecutar el resto o parte del script bajo otro usuario:
fuente
whoami
lugar delid
cual devolverá el nombre en lugar de la identificaciónsudo
puede ser conveniente, pero no es bueno si no está listo para usar (como en AIX).su -c 'commands'
Es la respuesta correcta.Debe ejecutar todos los comandos de diferentes usuarios como su propio script. Si es solo uno o algunos comandos, entonces en línea debería funcionar. Si se trata de muchos comandos, probablemente sea mejor moverlos a su propio archivo.
fuente
su -s /bin/bash
.Aquí hay otro enfoque, que fue más conveniente en mi caso (solo quería eliminar los privilegios de root y hacer el resto de mi script desde un usuario restringido): puede hacer que el script se reinicie desde el usuario correcto. Supongamos que se ejecuta como root inicialmente. Entonces se verá así:
fuente
runuser -u $user -- "$@"
, como se indica en su (1)exec su "$user" "$0" -- "$@"
--
es realmente útil.Utilizar en su
sudo
lugarEDITAR : Como Douglas señaló, no se puede utilizar
cd
ensudo
puesto que no es una externa de comando. Tienes que ejecutar los comandos en una subshell para hacer elcd
trabajo.Se le puede pedir que ingrese la contraseña de ese usuario, pero solo una vez.
fuente
sudo
puede ser conveniente, pero no es bueno si no está listo para usar (como en AIX).su -c 'commands'
Es la respuesta correcta.No es posible cambiar de usuario dentro de un script de shell. Las soluciones alternativas que usan sudo descritas en otras respuestas son probablemente su mejor opción.
Si está lo suficientemente loco como para ejecutar scripts perl como root, puede hacerlo con las
$< $( $> $)
variables que contienen uid / gid real / efectivo, por ejemplo:fuente
Esto funciono para mi
Separé mi "aprovisionamiento" de mi "inicio".
entonces en mi start_env.sh
fuente
Inspirado por la idea de @ MarSoft pero cambié las líneas de la siguiente manera:
Solía
sudo
permitir una contraseña menos ejecución del script. Si desea ingresar una contraseña para el usuario, elimine elsudo
. Si no necesita las variables de entorno, elimine-E
de sudo.El
/usr/bin/bash -l
asegura, que losprofile.d
scripts se ejecutan para un entorno inicializado.fuente
sudo
puede ser conveniente, pero no es bueno si no está listo para usar (como en AIX).su -c 'commands'
Es la respuesta correcta.sudo
. De hecho, sudo no es tan simple, en muchos casos necesita inclusosudo -E
una entrada de configuración en sudoers.d para permitir la ejecución sin tty con!requiretty
. Pero hay muchos casos en los que sudo es necesario para secuencias de comandos llamadas automáticas, donde un diálogo de contraseña puede interferir. Por lo tanto, no lo eliminaría de una solución estándar."$@"
dentro de una cadena significa que los argumentos más allá de la primera se agregan en una cadena separada, no incluida en el-c
argumento. Si usted quiere que sea seguro, es posible queprintf -v arg_q '%q ' "$0" "$@"
a continuación, utilizarsu "$USERNAME" -c "/usr/bin/bash -l $arg_q"
COMMANDARGS=$@
resuelve el problema con-c
. Los argumentos con espacios no eran un problema antes, pero implementé su buen aporte. Solo tuve que hacer algunos experimentos para que funcionara. He editado la pregunta y espero no haber pegado otro error. Gracias por tu comentario, humillante pero necesario.