What is the purpose of the bash `suspend` builtin command?

That's the equivalent of pressing Ctrl+Z in other commands.

It suspends the shell and gives control back to parent shell or process if any.

Example:

zsh$ bash
bash-4.4$ cd /
bash-4.4$ suspend
zsh: suspended (signal)  bash
zsh$ fg
[1]  + continued  bash
bash-4.4$ pwd
/

The feature comes from csh, the shell of BSD (where job control comes from) in the early 80s.

In AT&T ksh, it's a builtin alias for kill -s STOP $$ (yes, without the quotes!)

In your case, bash was probably the one started directly by the terminal emulator. And your terminal emulator didn't expect the process to be suspended.

That bash was a session leader. If the session leader is suspended, if we take the view of old time terminals, the user will have no way to resume it.

bash addresses that by refusing to suspend if it's a login shell. But in your case, your terminal emulator probably doesn't start bash in login mode, so that safeguard is not in place.

zsh and mksh don't have the problem because they send a SIGTSTP (the one also sent upon Ctrl+Z) signal like csh instead of SIGSTOP (and to the caller's process group for mksh like in csh, and to the main process group of the shell for zsh, not the $$ process alone). SIGTSTP is ignored when delivered to an orphaned process group, and the group of the leader qualifies. The idea is that SIGTSTP should not suspend something that is not resumable by a user.

In mksh or yash, one can also use suspend to have a subshell suspend itself:

$ (set -x; sleep 1; suspend; sleep 2)
+ sleep 1
+ suspend
[1] + Stopped(SIGSTOP)     (set -x; sleep 1; suspend; sleep 2)
$ fg
[1] (set -x; sleep 1; suspend; sleep 2)
+ sleep 2

That wouldn't work with zsh that sends the SIGTSTP to the main process group instead of the caller. In any shell that has kill builtin, one can always use kill -s TSTP 0 instead.


If you start a shell from another shell, you can suspend the inner one. Say when using su, and wanting to switch back to the regular user for a moment:

user$ su
Password: ...
root# do something
root# suspend
user$ do something as the ordinary user again
user$ fg
root# ...

(If you do that, don't forget the privileged shell open in the background...)

Similarly, if you escape to a shell from some other program (the ! command in e.g. less), you can still suspend the shell. But I wouldn't expect many other programs to handle it nicely when they launch a subprocess, which then suspends itself.