2012-04-19 9 views
52

Quiero escribir un script de shell para automatizar una serie de comandos. El problema es que algunos comandos DEBEN ejecutarse como superusuario y algunos comandos NO DEBEN ejecutarse como superusuario. Lo que he hecho hasta ahora es algo como esto:¿Cómo escribir un script de shell que ejecuta algunos comandos como superusuario y algunos comandos no como superusuario, sin tener que cuidarlo?

#!/bin/bash 

command1 
sudo command2 
command3 
sudo command4 

El problema es que esto significa que alguien tiene que esperar hasta comando1 termina antes de que se le pida una contraseña, entonces, si Command3 toma el tiempo suficiente, lo harán a continuación, tiene que esperar a que command3 termine. Sería bueno si la persona pudiera levantarse y marcharse, luego regresar una hora más tarde y terminar. Por ejemplo, la siguiente secuencia de comandos tiene este problema:

#!/bin/bash 

sleep 310 
sudo echo "Hi, I'm root" 
sleep 310 
sudo echo "I'm still root?" 

¿Cómo puedo hacerlo de modo que el usuario sólo pueden introducir su contraseña una vez, al principio, y luego a pie?

Actualización:

Gracias por las respuestas. Estoy corriendo en Mac OS X Lion y corrió el guión de Stephen P y tiene resultados distintos: (también agregué $ HOME)

[email protected] scratch$ ./test2.sh 
uid is 501 
user is pair 
username is 
home directory is /Users/pair 
[email protected] scratch$ sudo ./test2.sh 
Password: 
uid is 0 
user is root 
username is root 
home directory is /Users/pair 

Respuesta

42

archivo sutest

#!/bin/bash 
echo "uid is ${UID}" 
echo "user is ${USER}" 
echo "username is ${USERNAME}" 

plazo es: `./sutest' me da

uid is 500 
user is stephenp 
username is stephenp 

pero usando sudo: sudo ./sutest da

uid is 0 
user is root 
username is stephenp 

De modo que conserva el nombre de usuario original en $ NOMBRE DE USUARIO cuando se ejecuta como sudo.Esto conduce a una solución similar a lo que publican otros:

#!/bin/bash 
sudo -u ${USERNAME} normal_command_1 
root_command_1 
root_command_2 
sudo -u ${USERNAME} normal_command_2 
# etc. 

Sólo sudo para invocar el script en el primer lugar, se le solicitará la contraseña de una sola vez.


originalmente escribió esta respuesta en Linux, que tiene algunas diferencias con OS X

OS X (estoy probando esto en Mountain Lion 10.8.3) tiene una variable de entorno SUDO_USERcuando Está ejecutando sudo, que puede usarse en lugar de USERNAME anterior, o para ser más multiplataforma, el script podría verificar si SUDO_USER está configurado y usarlo si es así, o usar USERNAME, si está establecido.

Cambiar el guión original para OS X, se hace ...

#!/bin/bash 
sudo -u ${SUDO_USER} normal_command_1 
root_command_1 
root_command_2 
sudo -u ${SUDO_USER} normal_command_2 
# etc. 

Un primer intento por lo que es multiplataforma podría ser ...

#!/bin/bash 
# 
# set "THE_USER" to SUDO_USER if that's set, 
# else set it to USERNAME if THAT is set, 
# else set it to the string "unknown" 
# should probably then test to see if it's "unknown" 
# 
THE_USER=${SUDO_USER:-${USERNAME:-unknown}} 

sudo -u ${THE_USER} normal_command_1 
root_command_1 
root_command_2 
sudo -u ${THE_USER} normal_command_2 
# etc. 
+0

También se puede hacer una concha script que es propiedad de root y tiene el bit 'suid' establecido, pero que puede ser peligroso si no lo haces bien. Cada vez que ejecuta scripts de shell como root, puede considerar usar 'trap' para manejar señales. http://www.shelldorado.com/goodcoding/tempfiles.html tiene algunos ejemplos. –

+0

Extraño, en realidad obtengo resultados diferentes. Esto es en Mac OS X Lion: 'par @ abadía cero $/test2.sh'
' UID es 501'
'usuario es pair'
' nombre de usuario es ''
directorio principal es/Users/par. ''
par @ abadía cero $ sudo ./test2.sh ''
Contraseña: ''
uid es 0'
'usuario es root'
' 'nombre de usuario es root' directorio principal
es/Users/pair'
'pair @ abbey scratch $ sudo -u pair ./test2.sh'
'uid es 501'
'usuario está pair'
' 'nombre de usuario es directorio principal pair'
es/Users/pair'
speedarius

+0

Lo siento por el formato del comentario anterior; Estoy actualizando la publicación original ahora ... – speedarius

9

Debe ejecutar toda su secuencia de comandos como superusuario. Si desea ejecutar algún comando como superusuario no, utiliza "-u" opción de sudo:

#!/bin/bash 

sudo -u username command1 
command2 
sudo -u username command3 
command4 

Cuando se ejecuta como root, sudo no pide una contraseña.

3

Si utiliza esto, compruebe man sudo también:

#!/bin/bash 

sudo echo "Hi, I'm root" 

sudo -u nobody echo "I'm nobody" 

sudo -u 1000 touch /test_user 
3

Bueno, usted tiene algunas opciones.

Puede configurar sudo para que no solicite una contraseña. Esto no es recomendable debido a los riesgos de seguridad.

Puede escribir un script esperar para leer la contraseña y proporcionarla a sudo cuando sea necesario, pero eso es torpe y frágil.

Yo recomendaría diseñar la secuencia de comandos para ejecutar como root y soltar sus privilegios cuando no sean necesarios. Simplemente tiene sudo -u someotheruser command para los comandos que no requieren root.

(Si tienen que ejecutarse específicamente como el usuario que invoca la secuencia de comandos, entonces puede hacer que la secuencia de comandos guarde el uid e invocar una segunda secuencia de comandos mediante sudo con la identificación como argumento, para que sepa a quién ...)

Cuestiones relacionadas