qué shell usará sudo para ejecutar un script de shell sin la línea shebang

qué shell usará sudo para ejecutar un script de shell sin la línea shebang

Mi entorno es Ubuntu 12.04 LTS y la sudoversión es 1.8.3p1.

Primero inicio sesión como usuario normal:

$ whoami
fin

$ cat /etc/passwd | grep -i "root\|fin"
root:x:0:0:root:/root:/bin/bash
fin:x:1000:1000:This is a normal user:/home/fin:/bin/bash

$ ls -l /bin/sh
lrwxrwxrwx 1 root root 4 Mar 30  2012 /bin/sh -> dash

$ ls -l /bin/bash
-rwxr-xr-x 1 root root 920788 Apr  3  2012 /bin/bash

$ echo $SHELL
/bin/bash

$ ps | grep "$$" | awk '{ print $4 }'
bash

$ ls -l ./test.sh
-rwxr-xr-x 1 fin fin 37 Sep 27 16:46 test.sh

$ cat ./test.sh
ps | grep "$$" | awk '{ print $4 }'

$ ./test.sh
bash

$ sudo ./test.sh
sh

Supongo que el último resultado también debería serlo bashporque /etc/passwdmuestra que la raíz usa bash, ¿me falta algún punto al respecto sudo?

Respuesta1

Utiliza _PATH_BSHELLcomo execvp()que en Linux se define como /bin/shen /usr/include/paths.h. Eso debería ser lo mismo que cuando se ejecuta con envo find -execpor ejemplo.

Ciertamente no debería utilizar el shell de inicio de sesión del usuario. El hecho de que estés viendo basharriba se debe a que es bash(el shell en el que ingresas esa línea de comando) el que intenta ejecutarlo y cuando recibe un ENOEXECcódigo de error execvedecide interpretarlo consigo mismo (en shmodo de compatibilidad).

Respuesta2

Debido a que no usa -sla opción, sudousará _PATH_BSHELL(que está definida en /usr/include/paths.hUbuntu 12.04 LTS) para configurarla para $SHELLque se ejecute. Mirando el sudocódigo fuente:

/* Stash user's shell for use with the -s flag; don't pass to plugin. */
    if ((ud->shell = getenv("SHELL")) == NULL || ud->shell[0] == '\0') {
    ud->shell = pw->pw_shell[0] ? pw->pw_shell : _PATH_BSHELL;
    }

Si usa -sla opción, sudousará su $SHELLen lugar de _PATH_BSHELL:

$ cat ./test.sh
ps | grep "$$" | awk '{ print $4 }'

$ ./test.sh
bash

$ sudo -s ./test.sh
bash

Respuesta3

El kernel sólo puede ejecutar imágenes binarias ejecutables. Entonces, ¿cómo se ejecutan los scripts? Después de todo, puedo escribir my_script_without_shebangen el símbolo del shell y no aparece ningún ENOEXECerror. La ejecución del script no la realiza el kernel, sino el shell. El código ejecutivo en el shell generalmente se parece a:

/* try to run the program */
execl(program, basename(program), (char *)0);

/* the exec failed -- maybe it is a shell script without shebang? */
if (errno == ENOEXEC)
    execl ("/bin/sh", "sh", "-c", program, (char *)0);

Puede verificarlo rastreando un script de shell ficticio sin shebang:

cat > /tmp/foo.sh <<EOF
echo
EOF

chmod u+x /tmp/foo.sh

strace /tmp/foo.sh 2>&1 | grep exec
execve("/tmp/foo.sh", ["/tmp/foo.sh"], [/* 28 vars */]) = -1 ENOEXEC (Exec format error)

Entonces, la ejecución continúa como lo describió Stephane: se usa el shell predeterminado (en el fragmento de código anterior está codificado).Estas bonitas preguntas frecuentes sobre UNIXpuedo responder más.

información relacionada