scripting:terminalcodes

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
scripting:terminalcodes [2012/08/17 11:48]
ormaaj Mandelbrot
scripting:terminalcodes [2019/08/23 13:22]
artmieu
Line 3: Line 3:
 {{keywords>​bash shell scripting colors cursor control vt100 ansi}} {{keywords>​bash shell scripting colors cursor control vt100 ansi}}
  
-Terminal (control-)codes are needed ​to give specific commands to your terminal. This can be related to switching colors or positioning the cursor, ​simply everything ​that can't be done by the application itself.+Terminal (control) codes are used to issue specific commands to your terminal. This can be related to switching colors or positioning the cursor, ​i.e. anything ​that can't be done by the application itself.
  
  
 ===== How it technically works ===== ===== How it technically works =====
  
-A terminal control code is a special sequence of characters that is printed (like any other text). If the terminal understands the code, it won't display the character-sequence,​ but will perform some action. You can always ​print the codes with a simple ''​echo''​ command ​- for the application,​ it's nothing special.+A terminal control code is a special sequence of characters that is printed (like any other text). If the terminal understands the code, it won't display the character-sequence,​ but will perform some action. You can print the codes with a simple ''​echo''​ command.
  
-__**Note:​**__ I see that codes referenced as "Bash colors"​ sometimes (several "Bash tutorials"​ etc...): That's a retarded and completely incorrect definition.+__**Note:​**__ I see codes referenced as "Bash colors"​ sometimes (several "Bash tutorials"​ etc...): That's a completely incorrect definition.
  
 ===== The tput command ===== ===== The tput command =====
  
-Because there'​s a large number of different terminal control languages, usually a system has an intermediate-layer to talk to it. The real codes are looked up in a database **for the currently detected terminal type** and you give standardized requests to an API or (from the shell) to a command.+Because there'​s a large number of different terminal control languages, usually a system has an intermediate ​communication ​layer. The real codes are looked up in a database **for the currently detected terminal type** and you give standardized requests to an API or (from the shell) to a command.
  
-One of these commands is ''​tput'' ​- it accepts a set of acronymes ​and parameters ​for them, looks up the correct ​codes for the detected terminal in the ''​terminfo''​ database and prints the correct codes (the terminal hopefully understands).+One of these commands is ''​tput''​. Tput accepts a set of acronyms called //​capability names// ​and any parameters, ​if appropriate,​ then looks up the correct ​escape sequences ​for the detected terminal in the ''​terminfo''​ database and prints the correct codes (the terminal hopefully understands).
  
 ===== The codes ===== ===== The codes =====
  
-In this list I'll focus to ANSI/VT100 control codes for the most needed ​actions - take it as quick reference. The documentation of your terminal or the ''​terminfo''​ database is always the preferred source when something is unclear! Also the ''​tput'' ​acronymes ​are the ones dedicated for ANSI escapes, usually!+In this list I'll focus on ANSI/VT100 control codes for the most common ​actions - take it as quick reference. The documentation of your terminal or the ''​terminfo''​ database is always the preferred source when something is unclear! Also the ''​tput'' ​acronyms ​are usually ​the ones dedicated for ANSI escapes!
  
-Also only listed the most relevant codes, of course, any ANSI or especially your nice terminal ​knows much more! But let'​s ​reduce to common shell scripting ;-)+I listed ​only the most relevant codes, of course, any ANSI terminal ​understands many more! But let'​s ​keep the discussion centered on common shell scripting ;-)
  
-Sometimes ​didn't find a matching ANSI escape ​or vice versa - you'll see a :?: as code then - feel free to mail me or fix it!+If couldn't find a matching ANSI escapeyou'll see a :?: as  ​the ​code. Feel free to mail me or fix it.
  
-The ANSI codes are always ​intoduced ​with an ESC character (ASCII 0x1B or octal 033) - this isn't part of the list, but **you should avoid to use the ANSI codes directly - use the ''​tput''​ command!**+The ANSI codes always ​start with the ESC character(ASCII 0x1B or octal 033) This isn't part of the list, but **you should avoid using the ANSI codes directly - use the ''​tput''​ command!**
  
 All codes that can be used with ''​tput''​ can be found in terminfo(5). (on OpenBSD at least) All codes that can be used with ''​tput''​ can be found in terminfo(5). (on OpenBSD at least)
-See [[http://​www.openbsd.org/​cgi-bin/​man.cgi?​query=terminfo&​apropos=0&​sektion=5&​manpath=OpenBSD+Current&​arch=i386&​format=html|OpenBSD'​s terminfo(5)]] under the __Capabilities__ section. ​ The //​cap-name//​ is the code to use with tput, a description of each code is also provided.+See [[http://​www.openbsd.org/​cgi-bin/​man.cgi?​query=terminfo&​apropos=0&​sektion=5&​manpath=OpenBSD+Current&​arch=i386&​format=html|OpenBSD'​s terminfo(5)]] under the __Capabilities__ section. ​ The //​cap-name//​ is the code to use with tput. A description of each code is also provided.
  
 ==== General useful ASCII codes ==== ==== General useful ASCII codes ====
Line 49: Line 49:
  
 ^ANSI^terminfo equivalent^Description^ ^ANSI^terminfo equivalent^Description^
-|''​[ <X> ; <Y> H''​\\ ''​[ <X> ; <Y> f''​|''​cup <X> <​Y>''​|Home-positioning to ''​X''​ and ''​Y''​ coordinates\\ :!: it seems that ANSI takes 1-1 as root while ''​tput'' ​takes 0-0| +|''​[ <X> ; <Y> H''​\\ ''​[ <X> ; <Y> f''​|''​cup <X> <​Y>''​|Home-positioning to ''​X''​ and ''​Y''​ coordinates\\ :!: it seems that ANSI uses 1-1 as home while ''​tput'' ​uses 0-0| 
-|''​[ H''​|''​home''​|Home-positioning ​to root (0-0)| +|''​[ H''​|''​home''​|Move cursor ​to home position ​(0-0)| 
-|''​8''​|''​sc''​|Save current cursor position| +|''​7''​|''​sc''​|Save current cursor position| 
-|''​9''​|''​rc''​|Restore ​current ​cursor position|+|''​8''​|''​rc''​|Restore ​saved cursor position|
 |:?: most likely a normal code like ''​\b''​|''​cub1''​|move left one space (backspace)| |:?: most likely a normal code like ''​\b''​|''​cub1''​|move left one space (backspace)|
-|VT100 ''​[ ? 25 l''​|''​civis''​|switch ​cursor invisible| +|VT100 ''​[ ? 25 l''​|''​civis''​|make cursor invisible| 
-|VT100 ''​[ ? 25 h''​|''​cvvis''​|switch ​cursor visible|+|VT100 ''​[ ? 25 h''​|''​cvvis''​|make cursor visible|
  
 ==== Erasing text ==== ==== Erasing text ====
Line 70: Line 70:
 |''​[ 1 m''​|''​bold''​|Set "​bright"​ attribute| |''​[ 1 m''​|''​bold''​|Set "​bright"​ attribute|
 |''​[ 2 m''​|''​dim''​|Set "​dim"​ attribute| |''​[ 2 m''​|''​dim''​|Set "​dim"​ attribute|
 +|''​[ 3 m''​|''​smso''​|Set "​standout"​ attribute|
 |''​[ 4 m''​|set ''​smul''​ unset ''​rmul''​ :?:|Set "​underscore"​ (underlined text) attribute| |''​[ 4 m''​|set ''​smul''​ unset ''​rmul''​ :?:|Set "​underscore"​ (underlined text) attribute|
 |''​[ 5 m''​|''​blink''​|Set "​blink"​ attribute| |''​[ 5 m''​|''​blink''​|Set "​blink"​ attribute|
Line 99: Line 100:
 | ''​[ 4 6 m'' ​ | ''​setab 6'' ​         | Set **background** to color #6 - **cyan** ​    | | ''​[ 4 6 m'' ​ | ''​setab 6'' ​         | Set **background** to color #6 - **cyan** ​    |
 | ''​[ 4 7 m'' ​ | ''​setab 7'' ​         | Set **background** to color #7 - **white** ​   | | ''​[ 4 7 m'' ​ | ''​setab 7'' ​         | Set **background** to color #7 - **white** ​   |
-| ''​[ 4 9 m'' ​ | ''​setaf 9'' ​         | Set **default** color as background color     |+| ''​[ 4 9 m'' ​ | ''​setab 9'' ​         | Set **default** color as background color     |
  
 ==== Misc codes ==== ==== Misc codes ====
Line 107: Line 108:
 Used capabilities:​ ''​smcup'',​ ''​rmcup''​ Used capabilities:​ ''​smcup'',​ ''​rmcup''​
  
-For sure, you've already ​seen those programs that restore the terminal contents after they did their work (like ''​vim''​). This can be done by the following ​codes:+You'​ve ​undoubtedly ​already ​encountered ​programs that restore the terminal contents after they do their work (like ''​vim''​). This can be done by the following ​commands:
 <​code>​ <​code>​
 # save, clear screen # save, clear screen
Line 121: Line 122:
 </​code>​ </​code>​
  
-Thanks to ''​greycat'' ​for finding ​this and sharing it!+These features require that certain capabilities exist in your termcap/​terminfo. ​ While ''​xterm'' ​and most of its clones (''​rxvt'',​ ''​urxvt'',​ etc) will support the instructions,​ your operating system may not include references to them in its default xterm profile. ​ (FreeBSD, in particular, falls into this category.) ​ If `tput smcup` appears to do nothing for you, and you don't want to modify your system termcap/​terminfo data, and you KNOW that you are using a compatible xterm application,​ the following may work for you:
  
-===== Bash examples =====+<​code>​ 
 +echo -e '​\033[?​47h'​ # save screen 
 +echo -e '​\033[?​47l'​ # restore screen 
 +</​code>​
  
-==== Hardcoded colors ====+Certain software uses these codes (via their termcap capabilities) as well. You may have seen the screen save/​restore in ''​less'',​ ''​vim'',​ ''​top'',​ ''​screen''​ and others. ​ Some of these applications may also provide configuration options to *disable* this behaviour. ​ For example, ''​less''​ has a ''​-X''​ option for this, which can also be set in an environment variable:
  
-__Directly inside the echo:__ 
 <​code>​ <​code>​
-echo -e 'It is \033[31mnot\033[39m intelligent ​to use \033[32mhardcoded ANSI\033[39m codes!'​+export LESS=X 
 +less /path/to/file
 </​code>​ </​code>​
  
-__With preset variables:__+Similarly, ''​vim''​ can be configured not to "​restore"​ the screen by adding the following to your ''​~/​.vimrc''​: 
 + 
 +<​code>​ 
 +set t_ti= t_te= 
 +</​code>​ 
 + 
 + 
 + 
 +=== Additional colors === 
 + 
 +Some terminal emulators support additional colors. The most common extension used by xterm-compatible terminals supports 256 colors. These can be generated by ''​tput''​ with ''​seta{f,​b} [0-255]''​ when the ''​TERM''​ value has a ''​-256color''​ suffix. 
 +[[https://​gist.github.com/​XVilka/​8346728#​now-supporting-truecolour|Some terminals]] also support full 24-bit colors, and any X11 color code can be written directly into a special escape sequence. ([[https://​gist.github.com/​XVilka/​8346728|More infos]]) Only a few programs make use of anything beyond 256 colors, and tput doesn'​t know about them. Colors beyond 16 usually only apply to modern terminal emulators running in graphical environments. 
 + 
 +The Virtual Terminal implemented in the Linux kernel supports only 16 colors, and the usual default terminfo entry for ''​TERM=linux''​ defines only 8. There is sometimes an alternate "​linux-16color"​ that you can switch to, to get the other 8 colors. 
 + 
 +===== Bash examples ===== 
 + 
 +==== Hardcoded colors ==== 
 <​code>​ <​code>​
-COL_NORM=$'​\033[39m+printf ​'%b\n' 'It is \033[31mnot\033[39m ​intelligent to use \033[32mhardcoded ​ANSI\033[39m codes!'​
-COL_RED=$'​\033[31m' +
-echo "​Beware,​ ${COL_RED}not all terminals${COL_NORM} support ​ANSI"+
 </​code>​ </​code>​
  
Line 153: Line 173:
 echo "​It'​s ${COL_RED}red${COL_NORM} and ${COL_GREEN}green${COL_NORM} - have you seen?" echo "​It'​s ${COL_RED}red${COL_NORM} and ${COL_GREEN}green${COL_NORM} - have you seen?"
 </​code>​ </​code>​
- 
- 
  
 ==== Misc ==== ==== Misc ====
Line 214: Line 232:
 ==== Mandelbrot set ==== ==== Mandelbrot set ====
  
-This is a slightly modified version of Charles Cooke'​s colorful Mandelbrot plot scripts ([[http://​earth.gkhs.net/​ccooke/​shell.html | original w/ screenshot]]) -- de-golfed, optimized a bit, and modernized to remove ​hard-coded terminal escapes. The ''​colorBox''​ function is [[http://​en.wikipedia.org/​wiki/​Memoization | memoized]] to collect ''​tput''​ output only when required and output a new escape only when a color change is needed. This limits the number of ''​tput''​ calls to at most 16, and cuts down on raw output by more than half. The ''​doBash''​ function uses integer arithmetic, is ksh93-compatible, and is almost identical ​to the original other than indenting and replacing the part that does output. The ksh93-only floating-point ''​doKsh''​ is re-arranged a bit more for performance,​ and almost 10x faster than ''​doBash''​ (thus the ksh shebang by default), but uses only features that don't make the Bash parser ​puke.+This is a slightly modified version of Charles Cooke'​s colorful Mandelbrot plot scripts ([[http://​earth.gkhs.net/​ccooke/​shell.html | original w/ screenshot]]) -- ungolfed, optimized a bit, and without ​hard-coded terminal escapes. The ''​colorBox''​ function is [[http://​en.wikipedia.org/​wiki/​Memoization | memoized]] to collect ''​tput''​ output only when required and output a new escape only when a color change is needed. This limits the number of ''​tput''​ calls to at most 16, and reduces ​raw output by more than half. The ''​doBash''​ function uses integer arithmetic, ​but is still ksh93-compatible ​(run as e.g. ''​bash ./​mandelbrot'' ​to use it). The ksh93-only floating-point ''​doKsh''​ is almost 10x faster than ''​doBash''​ (thus the ksh shebang by default), but uses only features that don't make the Bash parser ​crash.
  
 <​code>​ <​code>​
Line 221: Line 239:
 # Charles Cooke'​s 16-color Mandelbrot # Charles Cooke'​s 16-color Mandelbrot
 # http://​earth.gkhs.net/​ccooke/​shell.html # http://​earth.gkhs.net/​ccooke/​shell.html
-# Combined Bash/​ksh93 ​flavor ​by Dan Douglas (ormaaj)+# Combined Bash/​ksh93 ​flavors ​by Dan Douglas (ormaaj)
  
 function doBash { function doBash {
Line 227: Line 245:
  for ((P=10**8,​Q=P/​100,​X=320*Q/​cols,​Y=210*Q/​lines,​y=-105*Q,​v=-220*Q,​x=v;​y<​105*Q;​x=v,​y+=Y));​ do  for ((P=10**8,​Q=P/​100,​X=320*Q/​cols,​Y=210*Q/​lines,​y=-105*Q,​v=-220*Q,​x=v;​y<​105*Q;​x=v,​y+=Y));​ do
  for ((;​x<​P;​a=b=i=c=0,​x+=X));​ do  for ((;​x<​P;​a=b=i=c=0,​x+=X));​ do
- for ((;a*a+b*b<4*P*P&&​i++<​99;​a=((c=a)*a-b*b)/​P+x,​b=2*c*b/​P+y));​ do :+ for ((;a**2+b**2<4*P**2&&​i++<​99;​a=((c=a)**2-b**2)/​P+x,​b=2*c*b/​P+y));​ do :
  done  done
  colorBox $((i<​99?​i%16:​0))  colorBox $((i<​99?​i%16:​0))
Line 237: Line 255:
 function doKsh { function doKsh {
  integer i  integer i
- float a b c x=2.2 y=-1.05 X=3.2/cols Y=2.1/lines+ float a b c x=2.2 y=-1.05 X=3.2/cols Y=2.1/​lines ​
  while  while
- for ((a=b=i=0;​(c=a)*a+b*b<​=2&&​i++<​99&&​(a=a*a-b*b+x,​b=2*c*b+y);​));​ do :+ for ((a=b=i=0;​(c=a)**2+b**2<​=2&&​i++<​99&&​(a=a**2-b**2+x,​b=2*c*b+y);​));​ do :
  done  done
  . colorBox $((i<​99?​i%16:​0))  . colorBox $((i<​99?​i%16:​0))
Line 251: Line 269:
  
 function colorBox { function colorBox {
- (( $1 == lastclr )) || printf %s "​${colrs[lastclr=$1]:​=$(tput setaf "​$1"​)}"​+ (($1==lastclr)) || printf %s "​${colrs[lastclr=$1]:​=$(tput setaf "​$1"​)}"​
  printf '​\u2588'​  printf '​\u2588'​
 } }
Line 261: Line 279:
 ${KSH_VERSION+. doKsh} ${BASH_VERSION+doBash} ${KSH_VERSION+. doKsh} ${BASH_VERSION+doBash}
 </​code>​ </​code>​
 +
 +A much more sophisticated version by Roland Mainz can be found [[http://​svn.nrubsig.org/​svn/​people/​gisburn/​scripts/​mandelbrotset1.sh | here]]
  • scripting/terminalcodes.txt
  • Last modified: 2019/08/23 13:22
  • by artmieu