다른 여러가지 훌륭한 언어(C, Perl, Python)가 있음에도 불구하고 여전히 쉘을 사용하는 이유는 효율적인 작업을 위해서 일것이다. bash 는 사용자가 중복시간을 줄이고, 작업을 빠르고 효율적으로 할수 있도록 하기 위해서 history, 명령어치환 과 같은 여러가지 기능들을 제공한다.
bash(다른 쉘도 마찬가지)은 환경변수라는걸 사용한다. 환경변수는 쉘이 운용되는데 필요한 여러가지 값들을 가지고 있다. 대표적인 예로 SHELL 변수가 있다. 이변수에는 현재 로그인 유저가 사용하고 있는 쉘이 어떤건지에 대한 정보를 가지고 있다. 여러분이 현재 사용하는 쉘이 어떤건지 알고 싶다면 다음과 같이 하면된다.
[yundream@localhost yundream]$ echo $SHELL /bin/bash |
환경변수를 세팅하기 위해서는 export 라는 쉘 명령어를 사용한다.
[yundream@localhost yundream]$ export MY_NAME="yundream" [yundream@localhost yundream]$ echo $MY_NAME yundream |
history 는 이전에 내렸던 명령을 기억해서 다시 써먹으려고 할때 유용하다. 터미널에서 history 명령을 내림으로써 이전에 실행했던 명령어의 목록을 확인할수 있다.
[yundream@localhost yundream]$ history 1 micq 2 exit 3 make clean ... 454 vi /home/httpd/cont/httpd.conf 455 history |
"!" 는 히스토리 기능을 사용하기 위한 쉘 예약어이다. 이걸 사용하면 작업을 편하게 할수 있다. "!(문자열)" 하게 되면, 히스토리 목록중에서 (문자열)로 시작되는 가장 최근에 실행된 히스토리의 명령어를 불러와서 실행하게 된다. 위에서 454 번의 명령을 다시 실행하고 싶다면, !vi 하면 된다. 물론 !v 해도 관계없다.
히스토리는 grep 과 조합되어서 자주 사용한다.
[root@localhost /root]# history | grep configure 8 ./configure --with-apache=../apache-1.3.22 13 ./configure 14 ./configure i686-linux 15 ./configure --help [root@localhost /root]# !8 ./configure --with-apache=../apache-1.3.22 |
아래와 같은 상황을 가정해보자
[root@localhost /]# vp file1 file2 bash: vp: command not found |
[root@localhost /]# ^v^c cp file1 file2 |
Prompt 란 쉘이 사용자의 입력을 기다리고 있음을 유저에게 알려주기 위해서 사용한다. Prompt 를 잘 사용하게 되면 여러분이 어떤 호스트 에서 작업을 하는지, 혹은 몇시인지, 어떤 디렉토리에서 작업하고 있는지 등의 작업정보등을 얻을수 있다.
프롬프트 정보는 환경변수 PS1 에 저장된다. echo $PS1 해 보면 현재 설정된 프롬프트 정보를 볼수 있다. bash 는 효율적인 프롬프트 정보를 보여주기 위해서 몇개의 특수 문자 들을 제공하고 있다.
표 2. Prompt 예약어
\t | 현재 시간을 HH:MM:SS 형식으로 보여준다. |
\d | 날자를 "요일 월 일" 형식으로 보여준다. |
\s | 쉘의 이름을 보여준다. |
\w | 현재 작업디렉토리를 완전경로로 보여준다. |
\W | 현재 작업디렉토리의 이름을 보여준다. |
\u | 현재 사용자의 사용자명 |
\h | 호스트이름 |
\! | 이 명령의 히스토리 번호 |
\nnn | 8진수 nnn에 해당하는 문자 |
\[ | 비출력문자의 시퀀스를 시작한다. |
\] | 비출력문자의 시퀀스를 마친다. |
[root@localhost httpd]# export PS1="[\t \W]# " [17:40:37 html]# echo "성공적으로 바꼈군요" |
이렇게 해서 프롬프트를 변경시키는방법을 알았다. 그런데, 어떤 한텀 의 경우 한텀의 타이틀바 제목이 시시각각 바뀌는것을 본적이 있을 것이다. 이건 어떻게 하는것일까. ?
이건 bash 쉘의 환경변수인 PROMPT_COMMAND 를 사용하여 가능하다. PROMPT_COMMAND 에는 특정 명령어(스트립트 혹은 실행파일)가 값으로 들어가 있는데, 사용자에게 프롬프트가 떨어지기 전에 변수에 있는 명령이 실행된다.
[root@localhost /root]# export PROMPT_COMMAND="date" 월 11월 19 17:51:03 KST 2001 [root@localhost /root]# echo "hello world" hello world 월 11월 19 17:51:19 KST 2001 [root@localhost /root]# |
[root@localhost /home]# export PROMPT_COMMAND='echo -ne "\033]0;${USER}@${HOSTNAME}: ${PWD}\007"' |
하지만 단순히 사용자에게 시각적으로 그럴듯하게 보여주는것 외에도 PROMPT_COMMAND 를 응용하면 좀더 다양한 일들을 할수 있다. 다음장에서 이에 대해서 간단하지만 유용한 한가지 예를 들어 보도록 하겠다.
요즘 컴터업계 최대의 화두는 "보안"이다. 이런 대세에 맞추어서 사용자가 현재 무슨 명령을 사용중에 있는지 실시간으로 확인할수 있는 간단한 보안 프로그램? 을 작성해보도록 하겠다.
보통 이러한 사용자 명령을 실시간으로 추적하는 프로그램을 보안쉘 이라고 한다. - 물론 실지 보안쉘에는 이외에도, 파일보안, 디렉토리 보안, 프로세스보안 등과 같은 다양한 기능이 들어가지만 여기서는 사용자의 작업내용을 실시간으로 확인할수 있는 기능만 구현하겠다 - 보통 보안쉘을 만드는데는 많은 시간과 인내심이 필요하지만, 쉘의 특징을 조금만 알고 있다면, 시간과 노력을 단축시킬수가 있다.
PROMPT_COMMAND 를 이용하는 방법은 매우 간단하다. 사용자의 프롬프트가 떨어졌을때, 사용자의 이름, 사용자의 가장 최근의 명령어등을 가져와서 이를 파일로 만들거나 소켓을 통해서, 관리자에게 통보하도록 하면 된다. 쉘에서는 물론 history라는걸 제공하긴 하지만, history 는 실시간이 아니다. 일단은 쉘의 메모리에서 관리하고 있다가, 로그아웃 하면 그때 파일로 저장이 된다. 즉 로그아웃 하기 전까지는 무슨일을 하는지 통 알수가 없게 된다. 그리고 history 명령을 이용해서 편집 가능하다. 다음과 같은이름으로 moniter.sh 란 간단한 스크립트 파일을 작성한다.
LAST_COMMAND=`tail -1 /root/dump` CURRENT_COMMAND=`history 1` if [ "$LAST_COMMAND" != "$CURRENT_COMMAND" ] then echo "$CURRENT_COMMAND" >> /root/dump fi |
export PROMPT_COMMAND="/usr/bin/moniter.sh" |