5

I'm on OSX 10.11.1 and occasionally my bash terminal gets mangled. It often happens when I accidentally cat a binary file. The result can be seen on the image below. The output becomes weird, and I can't type ascii characters anymore.

enter image description here

Even though this happens occasionally, I couldn't find a way to consistently reproduce the issue. Online search recommends doing cat /bin/*, but that works sporadically, only after a couple dozen tries.

I want to do this so I can find an easy solution how to handle this in tmux.

How do I consistently get bash to a "mangled" state? Is there maybe a magic unicode character that can do this?

migrated from stackoverflow.com Nov 26 '15 at 21:21

This question came from our site for professional and enthusiast programmers.

10

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'
  • Thank you, this is the perfect answer and just what I was looking for. With printf '\033(0' command I can consistently get the terminal in the "mangled" state. – user80379 Nov 28 '15 at 22:39
  • Instead of using PROMPT_COMMAND in Bash, you could prepend the output of tput sgr0 to your PS1 (e.g. PS1="$(tput sgr0)$PS1") - saving a process every time you see the prompt. – Toby Speight Jan 14 '16 at 19:51
  • I think I also messed up with that exact DEC character set. unix.stackexchange.com/questions/454590/… . – neverMind9 Jul 11 '18 at 22:04
2

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy