Skip to content
Shell & TerminalFix Published Updated 3 min readViews unavailable

Fixing a Terminal Left Without Echo or Line Editing After a Command Crashes

A recovery and prevention guide for broken terminal state: blind reset commands, stty inspection, TTY targeting, job control, exact restoration, and traps.

If typed characters stop appearing, Enter no longer submits a line normally, or control keys print symbols after a full-screen program crashes, the terminal emulator may be healthy while the kernel TTY settings or escape-sequence modes remain altered. Recovery should restore the current TTY, then the faulty program should be fixed to return the exact state it borrowed.

Recover when input is invisible

Try typing this command even if you cannot see it, then press Enter:

stty sane

stty sane restores an implementation-defined collection of reasonable modes such as echo and canonical input. It is an emergency baseline, not the perfect restoration of custom settings. If Enter is not recognized, type Ctrl-J after the command because line feed may still terminate input when carriage-return translation is broken.

Then run:

reset

reset can reinitialize terminal-emulator modes and terminfo-derived state as well as TTY settings, and may clear the screen. If the shell itself is stopped or a foreground job still owns the terminal, use the terminal application’s interrupt/close control or log in from another session and inspect process groups before sending signals.

Do not run stty against an unrelated standard input. In a pipeline or script without a TTY on stdin, target the controlling terminal explicitly where supported:

stty sane </dev/tty

This fails appropriately if the process has no controlling terminal. Avoid changing /dev/console or every pseudo-terminal on the machine.

Determine what changed

Once readable, inspect:

stty -a </dev/tty
jobs -l
ps -o pid,ppid,pgid,tpgid,stat,command -t "$(tty | sed 's#/dev/##')"

Look for -echo, -icanon, changed control characters, output processing disabled, or a stopped foreground process. The ps construction is system-dependent; use the local tool’s TTY syntax. A terminal can also remain in alternate screen, mouse tracking, bracketed paste, hidden cursor, or application-keypad mode—those are escape-sequence states, not stty flags, which is why reset may help after stty sane.

Check whether the failing program crashed, was killed with SIGKILL, lost the SSH connection, or was suspended. SIGKILL cannot run cleanup. A robust application must minimize the window between mode change and installed recovery handlers, and should use a library that owns terminal lifecycle.

Save and restore exact prior state in scripts

For a small shell interaction:

old=$(stty -g </dev/tty) || exit 1
restore_tty() { stty "$old" </dev/tty; }
trap restore_tty EXIT HUP INT TERM

stty -echo </dev/tty || exit 1
IFS= read -r secret </dev/tty
restore_tty
trap - EXIT HUP INT TERM
printf '\n' >/dev/tty

The opaque stty -g form is intended for restoration on the same system. Quote it and pass it as an argument, never through eval. Make restoration idempotent and install traps before the risky interaction. Native full-screen programs also need suspend/resume handling: restore before stopping, reapply after continuation, and redraw.

Prove every exit path

Test normal completion, invalid input, initialization failure, Ctrl-C, Ctrl-, Ctrl-Z/resume, terminal resize, SSH disconnect, child crash, and forced termination. After each recoverable path, compare stty -g with the saved value and verify cursor, screen, paste, and mouse modes.

Run those tests from a disposable pseudo-terminal rather than the developer’s only shell. Tools such as a terminal multiplexer or a test harness built around a PTY can start the program, inject control bytes/signals, and query the resulting settings. Record both the termios snapshot and emitted escape stream. This catches a program that restores echo correctly but leaves mouse reporting, bracketed paste, or the cursor disabled in the emulator.

Emergency commands restore usability; prevention requires exact ownership. A terminal program should borrow state for the shortest possible period and return it across every path the operating system allows it to handle.

Related:

Sources:

Comments