Colors
ASCII 챠트에서 0x20 이하 문자들과 0x7F 는 A B C 1 2 3 와같이 화면에 표시되는 모양은 없지만 라인개행을 한다든지 backspace 로 문자를 삭제하는 등의 기능을 하는 control 문자입니다. 그 외 function 키나 방향키에 대한 값 들은 특수한 방법을 이용해 전송하는데요. 방법은 ascii 챠트에서 escape 문자에 해당하는 0x1b 문자를 먼저 보내고 뒤에 관련된 문자들(sequence)를 전송합니다 ( 그래서 escape sequence 라고 부릅니다 )
$ od -tax1 [enter]
^[OP^[OQ^[OR^[[A^[[B # f1 ~ f3 키, 위 아래 방향키를 누르고 [enter]
0000000 esc O P esc O Q esc O R esc [ A esc [ B nl
1b 4f 50 1b 4f 51 1b 4f 52 1b 5b 41 1b 5b 42 0a
# ctrl-d 로 종료
위의 od 명령을 이용해 function 키와 방향키를 눌렀을때의 키값을 조회해 보면 제일앞에 0x1b (esc) 문자가 나오는것을 볼 수 있습니다. 이렇게 escape sequence 를 전송받은 프로그램은 나름대로 해석하여 처리하게 됩니다.
Color 표시를 위한 escape sequence
터미널에 color 를 표시할 때도 escape sequence 를 터미널 프로그램에 전송해 처리하게 하는데 작성하는데 간단한 규칙이 있습니다.
1. escape
escape 문자는 다음 중에 하나를 사용할 수 있습니다.
\e , \x1b (16진수) , \033 (8진수)
2. [
시작을 나타냅니다.
3. style; foreground; background
style 값은 여러개를 적을 수 있습니다.
4. m
종료를 나타냅니다.
사용예 )
# \e 문자 처리를 위해 echo 명령에서 -e 옵션을 사용합니다.
echo -e "\e[0;31m red foreground"
echo -e "\e[0;44m blue background"
echo -e "\e[0;1m bright style"
echo -e "\e[0;31;44m red foreground, blue background"
echo -e "\e[01;31;44m bright style, red foreground, blue background"
# 다음에 이어지는 스트링에는 속성이 적용되지 않게 reset 합니다.
echo -e "\e[0m"
# 먼저 reset 한 후 속성을 적용합니다.
echo -e "\e[01;31m ..."
Color, Style 속성값
다음은 16 color terminal 에 적용할 수 있는 값입니다. style 값은 10 보다 작고 foreground 값은 30 번대, background 값은 40 번대를 사용하는 것을 알 수 있습니다. 값만으로 구분이 가능하므로 순서에 상관없이 적을 수 있습니다.
# Style
0 — Reset all attributes # 이전에 적용했던 속성을 reset 합니다.
1 — Bright
2 — Dim
4 — Underscore
5 — Blink
7 — Reverse # foreground 와 background 색상이 서로 바뀌어 표시됩니다.
8 — Hidden # 스트링이 보이지 않게됩니다.
# Foreground
30 — Black
31 — Red
32 — Green
33 — Yellow
34 — Blue
35 — Magenta
36 — Cyan
37 — White
# Background
40 — Black
41 — Red
42 — Green
43 — Yellow
44 — Blue
45 — Magenta
46 — Cyan
47 — White
스크립트로 전체 색상 프린트 해보기
#!/bin/bash
for fgcolor in {30..37} ; do
for bgcolor in {40..47}; do
for attr in 0 1 2 4 5 7; do
echo -en "\e[${attr};${fgcolor};${bgcolor}m"
echo -n " ${attr};${fgcolor};${bgcolor} "
echo -en "\e[0m"
done
echo
done
echo
done
-------------------------------------------------------
#!/bin/bash
for fgcolor in {30..37} {90..97} 39 ; do
for bgcolor in {40..47} {100..107} 49 ; do
for attr in 0 1 2 4 5 7 ; do
echo -en "\e[${attr};${bgcolor};${fgcolor}m"
echo -n " ${attr};${bgcolor};${fgcolor} "
echo -en "\e[0m"
done
echo
done
done
tput 명령을 이용한 설정
실제 터미널 장치가 메인프레임에 연결되어 사용되던 과거에는 터미널의 종류가 한두 가지가 아니었을 것이라는 것은 쉽게 짐작할 수 있습니다. 각각의 터미널 장치들은 제공하는 기능도 달랐고 control characters, escape seqeunces 를 이용한 commands 들도 틀렸다고 합니다. 그래서 이와같은 터미널들의 정보를 라이브러리로 만들어놓은 것이 terminfo (termcap 의 새로운 버전) 입니다 (우분투의 경우 /lib/terminfo 에서 볼수있습니다). terminfo 라이브러리를 이용하면 device independent 한 방법으로 프로그램 할 수 있습니다.
위에서 처럼 color escape sequence 를 직접 하드코드하면 다른 종류의 터미널을 emulation 하는 프로그램에서는 동일하게 동작하지 않을 수 있습니다. 실제로 Ctrl-Alt-F1 ~ F6 에서 제공되는 리눅스 가상콘솔은 $TERM 값이 linux 이고 gnome-terminal 같은경우는 xterm 으로 gnome-terminal 에서 설정한 색상은 가상콘솔 에서 다르게 보입니다.
tput 명령으로 설정을 하면 현재 터미널의 terminfo 정보를 이용해 값을 설정하므로 터미널 종류가 다른 환경에서도 동일하게 적용될 수 있습니다.
# foreground color 적용
tput setaf {color숫자}
# background color 적용
tput setab {color숫자}
# Style 속성 적용
tput bold – Set bold mode
tput dim – turn on half-bright mode
tput smul – begin underline mode
tput rmul – exit underline mode
tput rev – Turn on reverse mode
tput smso – Enter standout mode (bold on rxvt)
tput rmso – Exit standout mode
tput sgr0 – Turn off all attributes ( '\e[0m' 와 같은 기능 )
# Color 값
0 – Black
1 – Red
2 – Green
3 – Yellow
4 – Blue
5 – Magenta
6 – Cyan
7 – White
tput 명령은 매 실행시마다 terminfo 라이브러리를 조회하므로 속도가 느리다는 단점이 있습니다. 그러므로 먼저 사용되는 속성값들을 변수에 저장해 놓고 사용하는 것이 좋습니다.
사용예 )
color_reset=$(tput sgr0)
color_f_red=$color_reset$(tput setaf 1)
color_b_blue=$color_reset$(tput setab 4)
color_s_bold=$color_reset$(tput bold)
color_my1=$color_reset$(tput setaf 1)$(tput setab 4)
color_my2=$color_reset$(tput bold)$(tput setaf 1)$(tput setab 4)
echo "$color_f_red red foreground"
echo "$color_b_blue blue background"
echo "$color_s_bold bold style"
echo "$color_my1 red foreground, blue background"
echo "$color_my2 bold style, red foreground, blue background"
echo $color_reset
# 다음에 이어지는 스트링에는 속성이 적용되지 않게 reset 합니다.
$(tput sgr0)
# 먼저 reset 한 후 속성을 적용합니다.
$(tput sgr0)$(tput setaf 1) ...
스크립트로 전체 색상 프린트 해보기
#!/bin/bash
for fgcolor in {0..7} ; do
for bgcolor in {0..7}; do
for attr in sgr0 bold dim smul rev; do
echo -n "$(tput $attr)$(tput setaf $fgcolor)$(tput setab $bgcolor)"
echo -n " $attr;$fgcolor;$bgcolor "
echo -n "$(tput sgr0)"
done
echo
done
echo
done
Prompt 설정
Shell 이 $PS1 변수 값을 이용해 prompt 를 표시하는 과정을 eval echo \""$PS1"\"
명령으로 표현할 수 있는데
이때 eval 의 읽어들이는 단계를 거친 후 prompt escape sequences 가 처리되고 실행단계를 거친다고 볼 수 있습니다.
예를들어 이전 명령의 종료 상태 값을 prompt 에 표시하기 위해 PS1="hello \w $? > "
와 같이
double quotes 을 이용한다면 이때 이미 $?
변수값이 확장되어 대입된 상태가 되므로 항상 같은 값을 표시하게 됩니다.
그러므로 매번 prompt 가 표시될때 마다 새로운 $?
변수값이 표시되게 하려면 single quotes 을 사용하여 설정해야합니다.
AA=hello
PS1="$AA \w "'$?'" > "
또한 prompt escape sequences 중에 하나인 \$
는 double quotes 에서 $
로 escape 되므로 올바르게 적용하기 위해서는 single quotes 을 사용합니다.
AA=hello
PS1="$AA \w "'$? \$ '
color escape sequences 같은 non-printing 문자를 prompt 에 사용할 경우는 항상 \[ \]
으로 감싸줘야
커서의 포지션이 올바르게 설정됩니다.
AA=hello
color_reset="\[\e[0m\]"
color_f_red="\[\e[0;31m\]"
PS1="$AA \w $color_f_red"'$?'"$color_reset"' \$ '
-------------------------------------------------
color_reset="\[$(tput sgr0)\]"
color_f_red="$color_reset\[$(tput setaf 1)\]"
PS1="$AA \w $color_f_red"'$?'"$color_reset"' \$ '
Prompt Escape Sequences
Code | Description |
---|---|
\a | an ASCII bell (07) 문자 |
\d | "Weekday Month Date" 포멧의 날짜 (e.g., "Tue May 26") |
\D{format} | strftime(3) 함수에서 format 스트링이 사용되고 결과가 표시됩니다. { } 는 꼭 사용해야 되며 \D{} 와같이 empty 일 경우는 현재 로케일 설정에 따라 시간이 표시됩니다. |
\e | an ASCII escape (033) 문자 |
\h | the hostname 에서 첫번째 ' . ' 까지의 부분 |
\H | the hostname |
\j | 현재 background jobs 의 개수 |
\l | 현재 shell 의 terminal device 이름 (tty5) |
\n | newline |
\r | carriage return |
\s | 현재 shell 이름 ( the basename of $0 ) |
\t | 현재 시간 ( 24-hour HH:MM:SS 포멧 ) |
\T | 현재 시간 ( 12-hour HH:MM:SS 포멧 ) |
\@ | 현재 시간 ( 12-hour am/pm 포멧 ) |
\A | 현재 시간 ( 24-hour HH:MM 포멧 ) |
\u | 현재 사용자의 username |
\v | the version of bash (e.g., 2.00) |
\V | the release of bash, version + patch level (e.g., 2.00.0) |
\w | 현재 working directory ( $HOME 은 ' ~ ' 로 표시 ) |
\W | 현재 working directory 에서 basename 만 표시 ( $HOME 은 ' ~ ' 로 표시 ) |
\! | 이번 명령의 history number |
\# | 이번 명령의 command number ( 터미널을 열고 enter 로 명령을 사용할때 마다 하나씩 올라감 ) |
\$ | effective UID 가 0 이면 '#' 그렇지 않으면 '$' |
\nnn | 8 진수 문자 |
\\ | a backslash |
\[ | non-printing 문자 sequence 의 시작 ( 가령 color escape sequence 를 적용할때 사용해야됨 ) |
\] | non-printing 문자 sequence 의 종료 |