permisos - Cómo verificar si se ejecuta como root en un script de bash
scripts bash ejemplos (17)
Estoy escribiendo una secuencia de comandos que requiere permisos de nivel de raíz, y quiero hacerlo para que si la secuencia de comandos no se ejecuta como raíz, simplemente se haga eco de "Ejecute como raíz". y salidas.
Aquí hay un pseudocódigo para lo que estoy buscando:
if (whoami != root)
then echo "Please run as root"
else (do stuff)
fi
exit
¿Cómo podría (mejor y de forma segura) lograr esto? ¡Gracias!
Ah, solo para aclarar: la parte (hacer cosas) implicaría ejecutar comandos que en sí mismos requieren root. Así que ejecutarlo como un usuario normal solo generaría un error. Esto solo tiene la intención de ejecutar de manera limpia un script que requiere comandos de root, sin usar sudo dentro del script, solo estoy buscando algo de azúcar sintáctico.
0- Leer la documentación oficial de GNU Linux, hay muchas maneras de hacerlo correctamente.
1- Asegúrese de colocar la firma de shell para evitar errores de interpretación:
#!/bin/bash
2- este es mi guión
#!/bin/bash
if [[ $EUID > 0 ]]; then # we can compare directly with this syntax.
echo "Please run as root/sudo"
exit 1
else
#do your stuff
fi
Como @wrikken mencionó en sus comentarios, id -u
es un cheque mucho mejor para root.
Además, con el uso adecuado de sudo
, puede hacer que el script verifique si se está ejecutando como root. Si no es así, haga que se sudo
través de sudo
y luego ejecute con permisos de root.
Dependiendo de lo que haga el script, otra opción puede ser configurar una entrada sudo
para cualquier comando especializado que el script pueda necesitar.
Compruebe la raíz, salga si falla:
func_check_for_root() {
if [ ! $( id -u ) -eq 0 ]; then
echo "ERROR: $0 Must be run as root, Script terminating" ;exit 7
fi
}
func_check_for_root
Luego también está whoami y "quién soy yo", si quieres saber quién llamó a los versos de un script quién ejecuta actualmente un guión:
it@it-ThinkPad-W510:~$ who am i
it pts/19 2014-06-03 12:39 (:0.0)
it@it-ThinkPad-W510:~$ sudo who am i
[sudo] password for it:
it pts/19 2014-06-03 12:39 (:0.0)
(ver que incluso con sudo llamado le da a los usuarios id)
it@it-ThinkPad-W510:~$ sudo whoami
root
Por lo tanto,
if [ "$(whoami)" == "user" ]; then
echo "Executing the installer script"
else
echo "user is only allowed to execute the installer script"
fi
Compruebe la raíz:
ROOT_UID=0 # Root has $UID 0.
if [ "$UID" -eq "$ROOT_UID" ]
then
echo "You are root."
else
echo "You are just an ordinary user."
fi
exit 0
Probado y funcionando en root.
En esta respuesta, sea claro, supongo que el lector puede leer bash
y un script de shell POSIX como un dash
.
Creo que no hay mucho que explicar aquí, ya que las respuestas altamente votadas explican gran parte de esto.
Sin embargo, si hay algo más que explicar, no dudes en comentar, haré todo lo posible para llenar los vacíos.
Solución bash
optimizada para rendimiento y fiabilidad.
#!/bin/bash
AmIRoot()
{
! (( ${EUID:-0} || $(id -u) ))
}
AmIRoot && echo ''You are root'' || echo ''You are NOT root''
Explicación
Ya que es mucho más rápido leer la variable bash
estándar de $EUID
, el número de ID de usuario efectivo, que ejecutar el comando id -u
para POSIX -encontrar el ID de usuario, esta solución combina ambos en una función bien empaquetada. Si, y solo si, el $EUID
está disponible por alguna razón, se ejecutará el comando id -u
, asegurando que obtengamos el valor de retorno adecuado sin importar las circunstancias .
¿Por qué publico esta solución después de tantos años que el OP ha pedido?
Bueno, si veo correctamente, parece que falta un fragmento de código arriba.
Usted ve, hay muchas variables que deben tenerse en cuenta, y una de ellas es la combinación de rendimiento y fiabilidad .
Solución POSIX
#!/bin/sh
AmIRoot()
{
[ "$(id -u)" -eq 0 ]
}
AmIRoot && echo ''You are root'' || echo ''You are NOT root''
Conclusión
Por más que posiblemente no te guste, el entorno Linux se ha diversificado mucho. Lo que significa que hay personas a quienes les gusta mucho el bash
, que ni siquiera piensan en la portabilidad ( POSIX shells). Otros como yo prefieren las conchas POSIX . Es hoy en día una cuestión de elección y necesidades personales.
En un script de bash, tiene varias formas de verificar si el usuario en ejecución es root.
Como advertencia , no compruebe si un usuario es root utilizando el nombre de usuario root
. Nada garantiza que el usuario con ID 0 se llame root
. Es una convención muy fuerte que se sigue ampliamente, pero cualquiera puede cambiar el nombre del superusuario por otro.
Creo que la mejor manera de usar bash es usar $EUID
, desde la página del manual:
EUID Expands to the effective user ID of the current user, initialized
at shell startup. This variable is readonly.
Esta es una forma mejor que $UID
que podría cambiarse y no reflejar al usuario real que ejecuta el script.
if (( $EUID != 0 )); then
echo "Please run as root"
exit
fi
Una forma de abordar este tipo de problema es inyectando sudo
en mis comandos cuando no se ejecuta como root. Aquí hay un ejemplo:
SUDO=''''
if (( $EUID != 0 )); then
SUDO=''sudo''
fi
$SUDO a_command
De esta manera, mi comando es ejecutado por root cuando uso el superusuario o sudo
cuando es ejecutado por un usuario regular.
Si su script siempre debe ser ejecutado por root, simplemente configure los derechos en consecuencia ( 0500
).
Hay una simple comprobación de que un usuario es root.
La sintaxis de [[ stuff ]]
es la forma estándar de ejecutar un cheque en bash.
error() {
printf ''/E[31m''; echo "$@"; printf ''/E[0m''
}
if [[ $EUID -eq 0 ]]; then
error "This script should not be run using sudo or as the root user"
exit 1
fi
Esto también supone que desea salir con un 1 si falla. La función de error
es una característica que establece el texto de salida en rojo (no es necesario, pero es bastante elegante si me preguntas).
La variable de entorno $ EUID contiene el UID del usuario actual. El UID de la raíz es 0. Use algo como esto en su script:
if [ "$EUID" -ne 0 ]
then echo "Please run as root"
exit
fi
Nota: Si obtiene 2: [: Illegal number:
verifique si tiene #!/bin/sh
en la parte superior y cámbielo a #!/bin/bash
.
Muy simple forma de poner simplemente:
if [ "$(whoami)" == "root" ] ; then
# you are root
else
# you are not root
fi
La ventaja de usar esto en lugar de id
es que puede verificar si un determinado usuario no root también está ejecutando el comando; p.ej.
if [ "$(whoami)" == "john" ] ; then
# you are john
else
# you are not john
fi
Por lo que sé, la forma correcta de comprobarlo es:
if [ $(id -u) = "0" ]; then
echo "You are root"
else
echo "You are NOT root"
fi
Vea la sección "Pruebas de Raíz" aquí:
Se han dado algunas respuestas, pero parece que el mejor método es utilizar:
-
id -u
- Si se ejecuta como root, devolverá un id de 0.
Esto parece ser más confiable que los otros métodos, y parece que devuelve un id de 0 incluso si el script se ejecuta a través de sudo
.
Si la secuencia de comandos realmente requiere acceso a la raíz, entonces sus permisos de archivo deberían reflejar eso. Tener un script ejecutable de la raíz por usuarios no root sería una bandera roja. Le animo a que no controle el acceso con un if
check.
chown root:root script.sh
chmod u=rwx,go=r script.sh
Una forma sencilla de hacer que el script solo sea ejecutable por root es iniciar el script con la línea:
#!/bin/su root
prueba el siguiente código:
if [ "$(id -u)" != "0" ]; then
echo "Sorry, you are not root."
exit 1
fi
O
if [ `id -u` != "0" ]; then
echo "Sorry, you are not root."
exit 1
fi
id -u
es mucho mejor que whoami
, ya que algunos sistemas como Android pueden no proporcionar la palabra raíz.
Ejemplo:
# whoami
whoami
whoami: unknown uid 0
#!/bin/bash
# GNU bash, version 4.3.46
# Determine if the user executing this script is the root user or not
# Display the UID
echo "Your UID is ${UID}"
if [ "${UID}" -eq 0 ]
then
echo "You are root"
else
echo "You are not root user"
fi
Nota del editor: Si no necesita corchetes dobles, use los solteros para la portabilidad del código.
if [[ $(id -u) -ne 0 ]] ; then echo "Please run as root" ; exit 1 ; fi
o
if [[ `id -u` -ne 0 ]] ; then echo "Please run as root" ; exit 1 ; fi
:)