What is the right way to consistently mangle bash terminal?

This looks like the DEC special graphics character set.

Reading the xterm control sequences docs, it sounds like the terminal uses those when receiving ESC ( 0.

So you should be able to reproduce using

printf '\033(0'

or

printf '\033(0' > corrupt-my-terminal
cat corrupt-my-terminal

And get back using

printf '\033(B'

which according to the same page selects USASCII.


Other ways to restore the state include

tput sgr0  # resets all terminal attributes to their defaults

and

reset      # reinitializes the terminal

You could tput sgr0 in your PROMPT_COMMAND (bash), or precmd (zsh) to ensure it always gets reset automatically.


Or you could just make sure to use less, vim, or anything other than cat to view a file.

To make less act like cat and automatically quit if the file is under one page long, run less -FX, or do export LESS=-FX.

Or if you don't want to always use those less options, make a new alias, e.g.

alias c='less -FX'

The most common way for the graphics character set in a VT100 emulator to get selected accidentally is by receiving a Control-N character, also known as shift-out. If you cat a binary file and there's a byte in it with the value '\14', that can cause the terminal emulator to shift to the graphics character set. It is undone upon receiving a Control-O character, shift-in (or by a control sequence that resets the terminal). It is independent of bash or any other shell that may be running in the terminal emulator.

For a terminal emulator running inside a terminal emulator, the semantics can be a bit complex. For instance, here is how screen handles it:

When the boolean ‘G0’ capability is present in the termcap entry for the terminal on which screen has been called, the terminal emulation of screen supports multiple character sets. This allows an application to make use of, for instance, the VT100 graphics character set or national character sets. The following control functions from ISO 2022 are supported: ‘lock shift G0’ (‘SI’), ‘lock shift G1’ (‘SO’), ‘lock shift G2’, ‘lock shift G3’, ‘single shift G2’, and ‘single shift G3’. When a virtual terminal is created or reset, the ASCII character set is designated as ‘G0’ through ‘G3’. When the ‘G0’ capability is present, screen evaluates the capabilities ‘S0’, ‘E0’, and ‘C0’ if present. ‘S0’ is the sequence the terminal uses to enable and start the graphics character set rather than ‘SI’. ‘E0’ is the corresponding replacement for ‘SO’. ‘C0’ gives a character by character translation string that is used during semi-graphics mode.