¿Sudo su crea un terminal hijo?

9

Esto es lo que sucedió cuando ejecuté sudo suseguido deexit

$ sudo su
# exit
exit
$ 

El comando de salida no cierra mi emulador de terminal.

¿Es un terminal infantil?

Reeshabh Ranjan
fuente

Respuestas:

15

Una vez que ejecuta sudo suo se está creando un nuevo shell.su user

La ejecución exit(o Ctrl+ D) saldrá del nuevo shell de creación y lo regresará a su shell anterior.

  1. Punto de partida: bash shell se ejecuta en PID 25050:

    $ ps
      PID TTY          TIME CMD
    25050 pts/17   00:00:00 bash
    25200 pts/17   00:00:00 ps
  2. La ejecución sudo sucrea un nuevo proceso bash que se ejecuta en PID 25203:

    $ sudo su
    # ps
      PID TTY          TIME CMD
    25201 pts/17   00:00:00 sudo
    25202 pts/17   00:00:00 su
    25203 pts/17   00:00:00 bash
    25213 pts/17   00:00:00 ps
    # exit
  3. Salir sudo suy volver al punto de partida: bash shell se ejecuta en PID 25050:

    $ ps
      PID TTY          TIME CMD
    25050 pts/17   00:00:00 bash
    25214 pts/17   00:00:00 ps
    $
Yaron
fuente
Entonces, ¿se puede tratar como un caparazón secundario?
Reeshabh Ranjan
1
@ReeshabhRanjan - sí
Yaron
17

Mismo terminal, diferente caparazón.

Los procesos secundarios que ejecuta desde un shell, incluidos los shells secundarios, usan el mismo terminal automáticamente. Esto no es específico de sudoninguna manera; en general, así es como funciona cuando ejecuta cualquier programa desde su shell.

Los depósitos y las terminales son cosas diferentes. Un shell es lo que usa para ejecutar comandos en una terminal . Un shell puede operar de manera interactiva: le da un aviso, le da un comando, ejecuta el comando o muestra un error acerca de por qué no puede hacerlo, y el proceso se repite hasta que abandone el shell. O puede funcionar de manera no interactiva, ejecutando un script .

A pesar de que su terminal está (probablemente!) Emulado , no física , sin embargo, Unix sistemas operativos como Ubuntu asignar nodos de dispositivo a cada uno de sus terminales, y se puede comprobar qué terminal que se utiliza con el ttycomando. Por lo general será /dev/pts/0, /dev/pts/1, /dev/pts/2, etc , para una ventana de terminal o conexión SSH , o /dev/tty1, /dev/tty2, etc. , para las consolas virtuales . Realmente lo que ttyhace es decirle de qué terminal, si hay alguna, se está tomando la entrada ; ver abajo para más detalles.

ek@Io:~$ tty
/dev/pts/1
ek@Io:~$ bash
ek@Io:~$ tty
/dev/pts/1
ek@Io:~$ exit
exit
ek@Io:~$ sudo su
[sudo] password for ek:
root@Io:/home/ek# tty
/dev/pts/1
root@Io:/home/ek# exit
exit
ek@Io:~$

Puede ver que, aunque sudo sucrea un nuevo shell como explica muy bien Yaron , el terminal que está utilizando no cambia.

Por supuesto, hay otra forma de observar que el terminal es el mismo: todavía está escribiendo la entrada de la misma manera y en el mismo lugar, y leyendo la salida de la misma manera y en el mismo lugar.

Algunos detalles técnicos

La mayoría de los comandos que se ejecutan en un shell - tales como ls, cp, mv, rm, touch, wc, du, df, ssh, su, sudo, sh, bash, y muchos más - causa un proceso hijo que se creará. Este proceso secundario tiene su shell como padre pero es un programa separado. Por defecto, está conectado a la misma terminal que su shell.

Su shell todavía se está ejecutando, pero espera en segundo plano a que el programa finalice (o que lo suspenda ). Cuando el programa finaliza, el shell todavía se está ejecutando y reanuda la operación, solicitándole su próximo comando.

Estas son las principales excepciones:

Aunque realmente no consideraría esto como una excepción a los procesos secundarios que se conectan al mismo terminal que su padre, tenga en cuenta que un proceso que ejecuta desde un shell en un terminal no siempre tomará la entrada de ese terminal o enviará la salida a ese terminal :

Dado que el ttycomando solo verifica qué terminal es su entrada estándar, puede "engañarlo":

ek@Io:~$ tty
/dev/pts/1
ek@Io:~$ tty </dev/pts/0
/dev/pts/0

O, menos tortuosamente:

ek@Io:~$ tty </dev/null  # not a terminal
not a tty
ek@Io:~$ tty <&-         # closes the input stream
not a tty
Eliah Kagan
fuente