'ANSI escape code'에 해당되는 글 1건

  1. 2011.12.20 ANSI color

ANSI color

리눅스/일반 2011.12.20 15:12

ANSI color로 리눅스 프롬프트를 예쁘게... Com. Science

* 목차
1. ANSI color
1.1 ANSI escape code
1.2 ANSI color 예제
2. Linux prompt
2.1 프롬프트 변수
2.2 프롬프트에 색상 넣기


1. ANSI color
ANSI 컬러는 ANSI escape code의 기능중 하나이다. 원래 ANSI escape code는 터미널의 텍스트 포맷을 제어하기 위해서 만들어진 코드이며 현재 ISO/IEC-6429 표준으로 제정되어있다. 따라서 대부분의 UNIX, Linux, DOS, Windows 등은 터미널에서 ANSI escape code를 지원한다.(일부 기능은 지원하지 않을 수도 있다.)

여기서는 리눅스(or 유닉스 계열)의 사용자를 기준으로 설명할 것이며 DOS/Windows 사용자들은 어차피 이 기능을 잘 안쓰므로 알아봐야 별 의미가 없을수도 있다.(즉 윈도우 사용자들에게는 별 도움이 안되는 글이다.)

1.1 ANSI escape code
ANSI escape code를 사용하기 위해서는 ANSI escape code를 지원하는 터미널이 필요하다.
그러나 안심하라. 현재 대부분의 리눅스/유닉스의 터미널은 ANSI escape code를 지원한다.
(지원하지 않는 기능을 굳이 설명할 이유도 없는것 아닌가?)

이제 터미널을 하나 열고 echo -e "\e[33m"를 타이핑 해보자.
[sunyzero@dev1 ~]$ echo -e "\e[33m"
$[sunyzero@dev1 ~]$
echo 문이 실행된 후에는 프롬프트 색상이 모두 노란색으로 바뀌어 있음을 알 수 있다. 이 후 타이핑하는 모든 글자는 다 노랗게 보일 것이다. 원상복귀를 위해 echo -e "\e[m"명령을 타이핑 해두자.

앞서 예제의 "\e[33m"과 같은 형태를 ANSI escape sequence라고 부르는데, echo문에서 이를 출력하여 실행하려면 ANSI escape code를 인식하는 옵션인 -e를 같이 넣어줘야 한다. 넣지 않으면 그냥 문자열로 인식해서 단순출력해버린다.

또한 ANSI escape sequence에서 시작문자인"\e["는 CSI(Control Sequence Introducer)라고 부르며 뒤의 33m, m 같은 것이 ANSI escape sequence의 코드 내용 부분이 되겠다.

CSI의 \e는 ASCII코드의 ESC키를 의미하므로 ESC의 ASCII값인 8진수 033(=decimal 27)을 사용하여 \033으로 표기할 수도 있다. 따라서 위의 "\e[33m"는 "\033[33m"으로 써도 된다.
ANSI Escape sequence = CSI + n [;+ ...] + letter
CSI = \e[ = \033[
CSI 다음에 나오는 n은 숫자이며 복수개가 나올때는 세미콜론(;)으로 구분한다. 마지막의 영문자 1개는 ANSI escape sequence의 명령(command)에 해당한다. 예를 들어 T는 스크롤 다운, m은 색상 변경등의 기능을 가진다. 색상 변경은 SGR(Select Graphic Rendition)이라고 부른다.

여기서는 ANSI Escape code 중 색상만 다루므로 m 명령만 다루도록 할 것이다. 그 외 명령어는 하단의 [1]의 링크를 참고하라.



1.2 ANSI color 예제
ANSI의 색상에서 사용 가능한 색상 밑 기능 테이블은 다음과 같다. [1]
Intensity012345679
NormalBlack Red Green Yellow Blue Magenta Cyan White reset
BrightBlack Red Green Yellow Blue Magenta Cyan White
색상은 0부터 7까지 사용가능한데, 그냥 사용하는게 아니라 뒤의 30, 40, 90, 100을 더해서 사용한다. 즉 normal yellow는 33이 된다. 40을 더해서 43을 만들면 Bright 옵션이 켜지게 된다. 그러면 이제 30~, 40~ 따위의 코드를 정리해보자.
CodeEffectNote
0 Reset / Normal all attributes off
1 Intensity: Bold
2 Intensity: Faint not widely supported
3 Italic: on not widely supported. Sometimes treated as inverse.
4 Underline: Single
5 Blink: Slow less than 150 per minute
6 Blink: Rapid MS-DOS ANSI.SYS; 150 per minute or more
7 Image: Negative inverse or reverse; swap foreground and background
8 Conceal not widely supported
21 Underline: Double not widely supported
22 Intensity: Normal not bold and not faint
24 Underline: None
25 Blink: off
27 Image: Positive
28 Reveal conceal off
30–39 Set foreground color, normal intensity 3x, where x is from the color table above
40–49 Set background color, normal intensity 4x, where x is from the color table above
90–99 Set foreground color, high intensity aixterm
100–109 set background color, high intensity aixterm
(위의 Table은 하단 레퍼런스에 있는 위키[1]에서 인용했다.)

이제부터 예제를 보면서 실습하자. 가장 간단한 Hello world부터 시작해보자.
[sunyzero@dev1 ~]$ echo -e "\e[31mHello World\e[m"
Hello World
항상 마지막에 나오는 \e[m은 숫자가 생략되었으므로 \e[0m과 같다. 즉 Reset이다. 이렇게 하지 않으면 변경된 색상이 계속 적용되어 프롬프트 색이 이상하게 나오기 때문이다. 앞으로 ANSI 색상을 쓸 때는 마지막에 Reset을 넣는 것을 잊지말자. 그 외의 것은 설명할 것이 없으니 이번에는 여러 속성을 넣어본 것을 실습해보자.
[sunyzero@dev1 ~]$ echo -e "\e[96mHello \e[0;4;93mWorld\e[m"
HelloWorld
96에서 십자릿수의 90번대(90-99)는 위의 표에서 "90-99 Set foreground color, high intensity"라고 나온다. 일자릿수의 6번과 조합해보면 Bright Cyan색이 된다. 두번째 ANSI escape sequence는 0;4;93이 연달아 나오므로 0은 Reset, 즉 앞에서 설정된 bright cyan색을 우선 해제하고, 4는 underline, 93에서 십자릿수의 90번대(90-99)는 high inensity색상이며 그 중 3번은 Yellow계열이므로 진노랑색이 나온다.

* 참고: high intensity 글자를 쓰기 위해서 90-99번대의 숫자를 사용하는 방법외에도 코드 1번(bold, intensity)를 넣어도 결과는 같다. 즉 93m이나 1;33m 은 같은 결과이므로 편한대로 쓰면 된다.

그렇다면 이번에는 배경색까지 지정하는 연습으로 high intensity yellow 배경에 normal green색 글씨로 Hellow world를 써보자.




2. Linux prompt
리눅스(혹은 유닉스)의 bash 쉘에서는 PS1 환경변수를 바꾸면 현재 프롬프트를 변경할 수 있다.
bash쉘 외에 ksh나 POSIX sh쉘등도 PS1 환경변수를 바꾸면 쉽게 프롬프트가 변경된다.

환경변수를 설정하는 리눅스 명령은 export나 declare -x 를 사용하면 되는데, export가 더 많이 쓰이므로 여기 예제에서는 export명령을 기준으로 설명하겠다.


2.1 프롬프트 변수
리눅스의 bash 쉘 프롬프트 기본값은 "[유저명@호스트명 현재디렉토리]$"의 형태로 되어있다.(root유저는 맨 끝의 프롬프트 문자가 #으로 나타남)
이 중에 유저명은 \u이고 호스트명은 \h, 현재 작업디렉토리는 \W의 변수로 PS1 환경변수에 쓰여진다.
따라서 기본값 PS1은 "[\u@\h \w]$ "가 된다. 그러면 어떤 변수들을 사용할 수 있는지부터 알아보자.
variablenote
\a an ASCII bell character (07)
\d the date in "Weekday Month Date" format (e.g., "Tue May 26")
\D{format} the format is passed to strftime(3) and the result is inserted into the prompt string; an empty format results in a locale-specific time representation. The braces are required
\e an ASCII escape character (033)
\h the hostname up to the first ‘.’
\H the hostname
\j the number of jobs currently managed by the shell
\l the basename of the shell’s terminal device name
\n newline
\r carriage return
\s the name of the shell, the basename of $0 (the portion following the final slash)
\t the current time in 24-hour HH:MM:SS format
\T the current time in 12-hour HH:MM:SS format
\@ the current time in 12-hour am/pm format
\A the current time in 24-hour HH:MM format
\u the username of the current user
\v the version of bash (e.g., 2.00)
\V the release of bash, version + patch level (e.g., 2.00.0)
\w the current working directory, with $HOME abbreviated with a tilde (uses the $PROMPT_DIRTRIM variable)
\W the basename of the current working directory, with $HOME abbreviated with a tilde
\! the history number of this command
\# the command number of this command
\$ if the effective UID is 0, a #, otherwise a $
\nnn the character corresponding to the octal number nnn
\\ a backslash
\[ begin a sequence of non-printing characters, which could be used to embed a terminal control sequence into the prompt
\] end a sequence of non-printing characters
(* 위 변수목록은 man bash의 PROMPTING 부분에서 인용함)
위의 표에서 나온 것을 사용해서 유용한 프롬프트 예를 3가지 만들어보겠다. 시각편의성을 위해서 프롬프트는 red, 명령어 부분은 blue로 표기했다.

[sunyzero@dev1 pub]$
export PS1="\u:\w $ "
sunyzero:/var/ftp/pub $ export PS1="[\u@\h] \w\n[\@ \$ "
[sunyzero@dev1] /var/ftp/pub
[02:02 PM $
export PS1="[\D{%Y-%m-%d %H:%M:%S}] [\u@\h] \w\n\$ "
[2009-11-24 14:11:52] [sunyzero@dev1] /var/ftp/pub
$
첫번째는 아주 간결한 프롬프트로서 \u와 \w로 구성했다. 두번째는 2행짜리 프롬프트로서 첫째 행에는 유저,호스트,작업디렉토리를 배치하고 둘째 행에는 시간을 배치했다. 세번째도 2행짜리 프롬프트로서 모든 정보를 첫째 행에 배치하고 둘째 행을 넓게 쓰는게 특징이다.



2.2 프롬프트에 색상 넣기
이제 앞의 프롬프트에 색상을 넣는 작업을 할 시간이다. 색상은 자신의 입맛에 넣으면 된다.
필자는 다음과 같이 넣어보았다. 중간에 너무 길어서 \로 개행하고 다음라인에 타이핑했다.(맨끝의 \는 다음행 개행을 의미하며 다음행은 >으로 시작한다.)
$ export PS1="\e[1;37m[\e[36m\D{%Y-%m-%d %H:%M:%S}\e[37m] \
>
[\e[32m\u\e[31m@\e[33m\h\e[37m] \e[34m\w\e[m\n\$ "
[2009-11-24 14:58:04] [sunyzero@atom] /var/ftp/pub
$

이제 본인이 필요한 내용을 넣어서 본인만의 PS1을 만들면 된다.

그리고 위의 PS1 설정 명령은 홈디렉토리에 있는 .bashrc 파일에 넣어두면 매번 로그인할때 자동으로 실행된다.(아래는 .bashrc의 예제이다.)
# .bashrc

# Source global definitions
if [ -f /etc/bashrc ]; then
. /etc/bashrc
fi

# User specific aliases and functions
export PS1="\e[1;37m[\e[36m\D{%Y-%m-%d %H:%M:%S}\e[37m] \
[\e[32m\u\e[31m@\e[33m\h\e[37m] \e[34m\w\e[m\n\$ "


이상으로 허접한 PS1과 ANSI color에 대한 이야기를 마친다.


* Reference
[1] http://en.wikipedia.org/wiki/ANSI_escape_code
[2] Gentoo Linux Document - Prompt magic - http://www.gentoo.org/doc/en/articles/prompt-magic.xml

'리눅스 > 일반' 카테고리의 다른 글

screen 명령어  (0) 2012.10.16
리눅스에서 이전 폴더로 이동하기  (0) 2012.03.30
find 와 grep를 이용한 파일/문자열/디렉터리 찾기 및 치환  (0) 2012.02.02
ANSI color  (0) 2011.12.20
cron 사용법  (0) 2011.12.19
scp 를 이용한 리눅스 서버간 파일 전송  (1) 2011.11.04
Posted by 라판