
Estoy intentando escribir un script bash que
- el contexto cambia a otro usuario (root, en este caso)
- ejecuta un conjunto de comandos parai.cree un usuario (solicitando interactivamente al invocador el nombre de usuario) y luegoii.establece la contraseña de ese usuario
- obtiene un valor de retorno
- luego continúa haciendo cosas, con ese valor de retorno
Hasta ahora he probado una entrada << EOF (Figura 1), Una función (Figura 2), y extraer/ejecutar un script separado (Fig. 3). Sin embargo no he obtenido los resultados que necesito.
sudo su - << 'EOF'
# do stuff...
EOF
Figura 1
function myfunc()
{
local myresult='some value'
echo "$myresult"
}
Figura 2
sudo su - -c bash <(curl -fksSL https://<my-script-location>.sh)
Fig. 3
Respuesta1
sudo su - << 'EOF' # do stuff... EOF
Esto funciona, pero con una limitación: el script se pasa al shell en su entrada estándar, por lo que no puedes usar la entrada estándar para otra cosa, como leer el nombre del usuario a crear.
La forma sencilla de conservar la entrada estándar es pasar el comando de shell como argumento.
Tenga en cuenta que sudo su
es redundante: ejecuta el comando especificado como root, y ese también sudo
es el único propósito . su
Úselo sudo -i
en lugar de sudo su -
si desea ejecutar un shell de inicio de sesión como root (lo cual probablemente no sea necesario aquí) o sudo sh
simplemente ejecutar un shell como root.
sudo sh -c '
# do stuff...
'
Esto hace que sea incómodo utilizar una comilla simple en el fragmento de shell. Puedes usar'\''
para poner una comilla simple dentro del literal entre comillas simples. Si desea conservar la estructura del documento aquí, existen varias formas. Lo más sencillo es pasar el documento aquí.en un descriptor diferente. Sin embargo, esto requiere que la closefrom_override
opción esté activada en la configuración de sudo, lo cual no es el caso por defecto; de forma predeterminada, sudo
cierra todos los descriptores de archivos distintos de stdin, stdout y stderr.
sudo -C 3 sh -c '. /dev/fd/3' 3<<'EOF'
# do stuff...
EOF
Si desea que su código sea portátil para máquinas donde esta opción no está activada, puede leer el script desde un heredoc y pasarlo al shell como argumento.
script=$(cat <<'EOF'
# do stuff...
EOF
)
sudo sh -c "$script"
Alternativamente, si desea que el script sudo pueda leerse desde la terminal, puede pasar el cuerpo del script en la entrada estándar. Una limitación de este enfoque es que no permite redirigir la entrada del script general.
sudo sh <<'EOF'
exec </dev/tty
# do stuff...
EOF
Respuesta2
Siempre que el usuario que invoca sudo
pueda asignar un tty
:
Defaults someuser:requiretty
A ans se le han otorgado permisos para ejecutar los comandos necesarios como root:
Cmnd_Alias STUFF = /usr/bin/passwd, /usr/sbin/useradd
someuser ALL = STUFF
un script que contenga sudo
invocaciones será interactivo. Podrías pasar el nombre de usuario como argumento posicional:
sudo useradd $1
sudo passwd $1
y verifique el estado de la devolución como de costumbre con $?
.
Respuesta3
su -c '. /dev/fd/4' 4<<\SCRIPT
...automated stuff here...
....then for interactive...
exec </dev/tty
SCRIPT
Deberías hacerlo. Adapte esto para satisfacer sus necesidades, pero cambiará de contexto y el estado de retorno del shell será el mismo $?
cuando haya terminado.