usuario - sudoers linux
Ejecute un script de shell en el shell actual con el permiso sudo (6)
Básicamente sudo espera, un ejecutable (comando) a seguir y está proporcionando un .
De ahí el error.
Pruebe de esta manera $ sudo setup.sh
Para ejecutar un script de shell en el shell actual, necesitamos usar un punto .
o un comando de source
. Pero, ¿por qué no funciona con un permiso de sudo?
Tengo un script con permiso de ejecución llamado setup.sh
. Cuando uso un punto, obtengo esto:
$ sudo . ./setup.sh
sudo: .: command not found
El comando de origen también produce un error similar. ¿Me estoy perdiendo algo? ¿Qué debo hacer para ejecutar el script con el permiso sudo en el mismo shell?
Gracias por adelantado..
Creo que está confundido acerca de la diferencia entre el origen y la ejecución de un script.
Ejecutar un script significa crear un nuevo proceso y ejecutar el programa. El programa puede ser un script de shell o cualquier otro tipo de programa. Como es un subproceso, cualquier variable ambiental modificada en el programa no afectará al shell.
La fuente de un script solo se puede usar con un script bash (si está ejecutando bash). Efectivamente escribe los comandos como si los hubieras hecho. Esto es útil ya que permite que un script cambie las variables de entorno en el shell.
Ejecutar un script es simple, simplemente escriba la ruta al script. .
es el directorio actual. Entonces ./script.sh
ejecutará el archivo script.sh
en el directorio actual. Si el comando es un archivo único (por ejemplo, script.sh
), comprobará todas las carpetas en la variable PATH para encontrar el script. Tenga en cuenta que el directorio actual no está en PATH, por lo que no puede ejecutar un archivo script.sh
en el directorio actual ejecutando script.sh
, debe ejecutar ./script.sh
(a menos que el directorio actual esté en PATH , por ejemplo, puede ejecutar ls
mientras está en el directorio /bin
).
La fuente de una secuencia de comandos no utiliza la RUTA, y solo busca la ruta. Tenga en cuenta que la source
no es un programa; de lo contrario, no podría cambiar las variables del entorno en el shell actual. En realidad, es un bash construido en comando. Buscar /bin
y /usr/bin
- no encontrará un programa source
allí. Por lo tanto, para script.sh
un archivo script.sh
en el directorio actual, solo debe usar source script.sh
.
¿Cómo interactúa sudo con esto? Well sudo toma un programa y lo ejecuta como root. Por ejemplo, sudo ./script.sh
ejecuta script.sh
en un subproceso pero se ejecuta como raíz.
¿Qué hace sudo source ./script.sh
sin embargo? ¿Recuerda que la source
no es un programa (más bien un shell incorporado)? Sin embargo, Sudo espera un nombre de programa, por lo que busca un programa llamado source
. No encuentra uno, y entonces falla. No es posible generar un archivo que se ejecute como root, sin crear un nuevo subproceso, ya que no puede cambiar el corredor de un programa (en este caso, bash) después de que haya comenzado.
No estoy seguro de lo que realmente quería, pero espero que esto lo aclare.
Aquí hay un ejemplo concreto. Cree el archivo script.sh
en su directorio actual con los contenidos:
#!/bin/bash
export NEW_VAR="hello"
whoami
echo "Some text"
Hazlo ejecutable con chmod +x script.sh
.
Ahora observa lo que sucede con bash:
> ./script.sh
david
Some text
> echo $NEW_VAR
> sudo ./script.sh
root
Some text
> echo $NEW_VAR
> source script.sh
david
Some text
> echo $NEW_VAR
hello
> sudo source script.sh
sudo: source: command not found
Lo que estás tratando de hacer es imposible; su shell actual se está ejecutando bajo su ID de usuario habitual (es decir, sin root, el acceso que sudo
le proporcionaría), y no hay forma de otorgarle acceso de root . Lo que hace sudo
es crear un nuevo * sub * proceso que se ejecute como root. El subproceso podría ser solo un programa regular (por ejemplo, sudo cp ...
ejecuta el programa cp
en un proceso raíz) o podría ser una subcadena raíz, pero no puede ser el shell actual.
(En realidad, es incluso más imposible que eso, porque el comando sudo
se ejecuta como un subproceso del shell actual, lo que significa que, en cierto sentido, ya es demasiado tarde para hacer algo en el "shell actual", porque no es ahí se ejecuta.)
No estoy seguro si esto rompe las reglas pero
sudo bash script.sh
Parece funcionar para mi.
Si realmente desea " Ejecutar Llamar un script de shell en el shell actual con el permiso sudo" puede usar exec
para ...
reemplace el shell con un programa dado (ejecutándolo, no como un proceso nuevo)
Insisto en reemplazar "ejecutar" por "llamar" porque el primero tiene un significado que incluye la creación de un nuevo proceso y una identificación, donde este último es ambiguo y deja espacio para la creatividad, de la cual estoy lleno.
Considere este caso de prueba y mire de cerca a pid 1337
# Don''t worry, the content of this script is cat''ed below
$ ./test.sh -o foo -p bar
User ubuntu is running...
PID TT USER COMMAND
775 pts/1 ubuntu -bash
1408 pts/1 ubuntu /_ bash ./test.sh -o foo -p bar
1411 pts/1 ubuntu /_ ps -t /dev/pts/1 -fo pid,tty,user,args
User root is running...
PID TT USER COMMAND
775 pts/1 ubuntu -bash
1337 pts/1 root /_ sudo ./test.sh -o foo -p bar
1412 pts/1 root /_ bash ./test.sh -o foo -p bar
1415 pts/1 root /_ ps -t /dev/pts/1 -fo pid,tty,user,args
Take ''exec'' out of the command and this script would get cat-ed twice. (Try it.)
#!/usr/bin/env bash
echo; echo "User $(whoami) is running..."
ps -t $(tty) -fo pid,tty,user,args
if [[ $EUID > 0 ]]; then
# exec replaces the current process effectively ending execution so no exit is needed.
exec sudo "$0" "$@"
fi
echo; echo "Take ''exec'' out of the command and this script would get cat-ed twice. (Try it.)"; echo
cat $0
Aquí hay otra prueba usando sudo -s
$ ps -fo pid,tty,user,args; ./test2.sh
PID TT USER COMMAND
10775 pts/1 ubuntu -bash
11496 pts/1 ubuntu /_ ps -fo pid,tty,user,args
User ubuntu is running...
PID TT USER COMMAND
10775 pts/1 ubuntu -bash
11497 pts/1 ubuntu /_ bash ./test2.sh
11500 pts/1 ubuntu /_ ps -fo pid,tty,user,args
User root is running...
PID TT USER COMMAND
11497 pts/1 root sudo -s
11501 pts/1 root /_ /bin/bash
11503 pts/1 root /_ ps -fo pid,tty,user,args
$ cat test2.src
echo; echo "User $(whoami) is running..."
ps -fo pid,tty,user,args
$ cat test2.sh
#!/usr/bin/env bash
source test2.src
exec sudo -s < test2.src
Y una prueba más simple usando sudo -s
$ ./exec.sh
bash''s PID:25194 user ID:7809
systemd(1)───bash(23064)───bash(25194)───pstree(25196)
Finally...
bash''s PID:25199 user ID:0
systemd(1)───bash(23064)───sudo(25194)───bash(25199)───pstree(25201)
$ cat exec.sh
#!/usr/bin/env bash
pid=$$
id=$(id -u)
echo "bash''s PID:$pid user ID:$id"
pstree -ps $pid
# the quoted EOF is important to prevent shell expansion of the $...
exec sudo -s <<EOF
echo
echo "Finally..."
echo "bash''s PID:/$/$ user ID:/$(id -u)"
pstree -ps $pid
EOF
El método más fácil es escribir:
-
sudo /bin/sh example.sh