How do I start a second shell when in single user mode?

Solution 1:

There's a command specifically designed for this situation: openvt. Just run openvt from your shell on tty1 and you'll find a shell running on the first tty that didn't already have something on it (tty2 probably.) There are several options you might find useful; see the openvt man page.

Since this is not a login managed by getty, when you exit the new shell you won't see a login prompt come up. The tty will just go dead since there will be no processes running on it, but you will still be able to switch back and forth (Alt-F1 Alt-F2) and see what was on the screen when you exited the shell. The deallocvt command destroys ttys that are in this zombie-like state, returning to the original "Alt-F2 does nothing" state.

Originally these commands were called open and disalloc, but eventually somebody decided to change them because they were too generic and disallocate was judged to be "not a word".

In the old days it was common for the keyboard driver and init to be configured so that Alt+Up would run open, so it would act as a hotkey to spawn a shell on a new console. You may still find a remnant of that old configuration, commented out, in your /etc/inittab. (If you aren't using some fancy new init that doesn't have an inittab.)

There's a similar question here

Solution 2:

You could spawn another getty for whichever ttys you want. Boot into single user mode, then start up a getty on tty2:

root@host:~# /sbin/getty 38400 tty2 &

You may now Alt+F2 over to the new tty. Repeat for additional ttys as needed. You could probably do something cleaner and just configure /etc/inittab to automatically handle this in single user mode.

Solution 3:

You probably can do without an extra shell instance by using JOB CONTROL in your current shell. It is documented in the manpage of bash(1).

You can just suspend a task using the Ctrl+Z sequence by default, though it can be configured in your terminal in a different way, check the output of stty -a:

$ stty -a | grep susp
eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R;

You can check your jobs by issuing jobs:

# jobs
[1]   Stopped                 journalctl -f
[2]-  Stopped                 vim /etc/hosts
[3]+  Stopped                 tail -f /var/log/firewalld

Bring one of them to the foreground:

$ fg %3

Or resume it in the background:

$ bg %2

This method does not have many of the advantages of screen or tmux, but can be equally useful in some situations.