Does sudo su create a child terminal?

Once you execute sudo su or su user a new shell is being created.

Executing exit (or Ctrl+D) will exit the newly create shell and will return you to your previous shell.

  1. Starting point - bash shell is running on PID 25050:

    $ ps
      PID TTY          TIME CMD
    25050 pts/17   00:00:00 bash
    25200 pts/17   00:00:00 ps
    
  2. Running sudo su creates a new bash process which is running on 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. Exiting sudo su and returning to the starting point - bash shell is running on PID 25050:

    $ ps
      PID TTY          TIME CMD
    25050 pts/17   00:00:00 bash
    25214 pts/17   00:00:00 ps
    $
    

Same terminal, different shell.

Child processes you run from a shell, including child shells, use the same terminal automatically. This is not specific to sudo in any way--this is generally how it works when you run any program from your shell.

Shells and terminals are different things. A shell is what you use to run commands in a terminal. A shell can operate interactively--it gives you a prompt, you give it a command, it runs the command or shows an error about why it cannot, and the process repeats until you quit the shell. Or it can operate noninteractively, running a script.

Even though your terminal is (probably!) emulated, not physical, nonetheless Unix-like operating systems like Ubuntu assign device nodes to each of your terminals, and you can check what terminal you are using with the tty command. It will usually be /dev/pts/0, /dev/pts/1, /dev/pts/2, etc., for a terminal window or SSH connection, or /dev/tty1, /dev/tty2, etc., for virtual consoles. Really what tty does is to tell you which terminal, if any, input is being taken from; see below for details.

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:~$

You can see that, even though sudo su creates a new shell as Yaron very well explains, the terminal you are using doesn't change.

Of course, there's another way to observe that the terminal is the same: you're still writing input the same way and in the same place, and reading output the same way and in the same place.

A few technical details

Most commands you run in a shell--such as ls, cp, mv, rm, touch, wc, du, df, ssh, su, sudo, sh, bash, and many more--cause a child process to be created. This child process has your shell as its parent but it is a separate program. By default, it is connected to the same terminal as your shell.

Your shell is still running, but it waits in the background for the program to terminate (or for you to suspend it). When the program terminates, the shell is still running and it resumes operation, prompting you for your next command.

These are the major exceptions:

  • Shell builtins like cd don't create a new process at all, unless they are used in a construct that employs a subshell (explained here), such as ( ) grouping and pipelines.
  • You can tell the shell not to wait for a command to complete by running the command asynchronously. You do this by ending the command with &. (your-command arguments... &)
  • You can use job control to change which command, if any, the shell waits for. With the disown builtin, you can detach jobs from your terminal.

Though I wouldn't really consider this an exception to child processes being connected to the same terminal as their parent, note that a process you run from a shell in a terminal will not always be taking input from that terminal or sending output to that terminal:

  • You can redirect any of the standard streams with the <, >, and >> operators.
  • You can pipe one command's output to another's input with |.

Since the tty command only checks which terminal its standard input is, you can "fool" it:

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

Or, less deviously:

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