2010년 8월 3일 화요일

명령어 히스토리 사용하기 - History

명령어 히스토리 사용하기

리눅스를 Gnome이나 KDE와 같은 윈도우 환경이 아닌 터미널 환경에서 주로 사용하는 경우가 많을 것이다. 이때 명령어를 좀 더 효율적으로 입력하는 방법을 알아보도록 하자. 긴 명령어를 짧게 줄이는 alias, 파이프나 세미콜론을 이용하여 여러 명령어를 한번에 실행하는 방법도 있지만 본 포스트에서 history를 이용하여 이미 실행한 명령어를 다시 실행하거나 수정하여 실행하는 방법을 알아보자.


1. 지난 명령어 보기
지난 명령어를 보는 방법은 터미널에서 간단히 history를 실행하는 것이다.


# history


history는 단순히 지난 명령어만을 표시할 것이다. 하지만 명령어가 실행된 시간은 여러가지 면에서 유용할 것이다. 아래와 같이 명령을 실행해보자.


# export HISTTIMEFORMAT='%d %B %Y %T CMD: '

# history

    1  03 August 2010 11:55:07 CMD: ls -al

    2  03 August 2010 11:55:12 CMD: ll

    3  03 August 2010 11:55:20 CMD: exit

    4  03 August 2010 22:48:39 CMD: ll

    5  03 August 2010 22:48:45 CMD: cd /var/www

    6  03 August 2010 22:48:46 CMD: ls

    7  03 August 2010 22:48:48 CMD: cd /var

#
 .bashrc에 HISTTIMEFORMAT='%d %B %Y %T CMD: '을 추가하면 히스토리 출력 형식이 유지될 것이다.

3. 히스토리 크기 조정하기
우분투 10.04는 히스토리 크기에 관한 설정은 .bashrc에 있다. 자신의 .bashrc 파일을 열어보면 아래와 같은 설정을 볼 수 있을 것이다.


HISTSIZE=1000             // 메모리 상에 저장되는 명령어 개수

HISTFILESIZE=1000      // .bash_history에 저장되는 명령어 개수
 

설정을 변경한 후 저장하자. 차후 로그인부터는 변경된 설정이 적용될 것이다.


4. 히스토리 파일 변경하기
명령어 히스토리는 기본적으로 로그아웃시 .bash_history에 저장될 것이다. 보안적인 측면에서 히스토리 파일을 기본 설정 값이 아닌 값으로 설정하는 것이 좋다. 우선 .bashrc 파일을 열어 아래와 같은 항목을 추가한다.


HISTFILE=~/.my_history


다시 로그인 하여 제대로 적용되었는지 확인한다. 이때 다음 로그인시에 위에 설정한 파일이 생성되어 있지 않을 것이다. 이는 설정 후 다시 로그인하게 되면 히스토리 파일명이 재설정되고 다시 로그하웃하여야 히스토리 파일이 생성되기 때문이다.


5. 명령어 다시 실행하기
우선 히스토리에 저장된 지난 명령어를 실행하는 가장 간단한 방법은 터미널 창에서 위 화살표를 이용하는 것이다. 한번씩 누를때 마다 지난 명령어들이 프롬프트에 나타날 것이다. 또한 히스토리 목록에서 번호 또는 상대적 위치를 이용하는 방법이 있다.

아래 명령어를 가장 최근 실행한 명령어라고 가정하자.


$ which firefox

$ make

$ ./foo -f foo.conf
$ vi foo.c bar.c

 

히스토리 라인 번호를 이용하는 방법

터미널에서 history를 실행하면 아래와 같이 출력될 것이다.


 $ history

    1  03 August 2010 13:54:42 CMD: which firefox

    2  03 August 2010 13:54:46 CMD: make

    3  03 August 2010 13:54:52 CMD: ./foo -f foo.conf

    4  03 August 2010 13:54:57 CMD: vi foo.c bar.c

    5  03 August 2010 13:55:28 CMD: history

$


 
각 명령어마다 번호가 매겨져 있어 이 번호를 참조하여 지난 명령어를 다시 실행할 수 있다.


 $ !1   //which firefox가 실행된다

 $ !2         // make가 실행된다

 $ !-4 // 뒤에서 4번째 명령이 실행된다. 여기서는 make가 실행된다

 $ !!         // 마지막 명령이 실행된다


키워드를 이용하는 방법

키워드가 포함된 가장 최근 명령어를 실행하는 방법은 아래와 같다.


 $ !which             // which로 시작하는 명령어를 실행한다. 여기서는 which firefox가 실행된다.

 $ !?firefox     // firefox가 포함된 명령어를 실행한다. 마찬가지로 which firefox가 실행된다.

 $ ^vi^cat^     // 마지막 명령어의 'vi'를 'cat'로 치환한 후 실행한다. 여기서는 cat foo.c bar.c가 된다.


6. 키워드로 검색하여 실행하기

위 키워드를 이용하는 방법에서는 실재로 명령어를 실행하기 전까지 어떤 명령어인지 확인할 수가 없다. 하지만 여기서 설명하는 방법을 사용하면 실행하기 전에 명령어를 확인할 수 있다. 터미널에서 Control+R을 누른 후 키워드를 입력하면 일치하는 최근 명령어가 표시될 것이다.


 $ // Ctrl+R을 누르면 reverse-i-search 프롬프트가 표시된다

(reverse-i-search)`firefox': which firefox       // 'firefox'를 입력하면 검색된 명령어가 표시된다.


검색어를 통해 검색 결과가 표시된 상태에서 오른쪽 혹은 왼쪽 화살표를 누르면 명령어를 수정할 수 있으니 요구에 맞게 수정하여 실행할 수 있다.


7. 지난 명령어 참조하여 실행하기

시스템을 관리하면서 긴 명령어을 실행하다 오타로 에러가 발생할 경우 해당 명령어를 수정하거나 특정 단어를 치환하여 실행할 필요가 있을 수 있다. 이때 Word Designator를 이용하여 지난 명령어를 수정하거나 명령어 인자만을 가져와 실행하는 방법을 살펴보도록 한다.


':' 문자 뒤에 word designator를 지정하여 조건에 맞는 문자열을 가져올 수 있다. Word designator와 modifier를 살펴보면 아래와 같다.


Word designator

0 (숫자 영) 가장 처음 단어. 일반적으로 실행 명령어 자체를 가리킨다.

n n번째 인자

^ 첫번째 인자. 1과 동일한 의미를 가진다.

$ 마지막 인자.

% '?string?' 검색 결과 일치하는 단어

x-y 문자범위. '-y'는 '0-y'과 일치한다.

* 0번째 단어를 제외한 모든 단어. '1-$'과 동일한 의미를 가진다.

x* 'x-$'과 동일한 의미를 가진다.

x- 'x-$'과 동일하지만 마지막 단어는 제외된다.


Modifier

h 경로명에서 마지막 부분을 제거한다.

t 경로명에서 처음 부분을 제거한다.

r .suffix 형태의 접미어를 제거한다.

e .suffix 형태의 접미어를 제외한 나머지 부분을 제거한다.

p 신규 명령어를 표시하고 실행하지 않는다.

q 치환된 단어를 가져오며 치환 작업을 멈춘다.

x 치환된 단어를 가져오며 스페이스, 탭, 개행문자를 기준으로 분리한다.

s/old/new/

old를 new로 최초 한번 치환한다. '/' 대신 다른 특수문자를 사용할 수 있다. 구분 문자를 문자의미 그대로 사용하기 위해서는 백슬래시(\)와 함께 사용한다. new에 '&'가 포함되어 있다면 '&'는 old로 치환될 것이다.

& 이전 치환 작업을 반복한다.

g 모든 일치하는 단어를 치환한다. gs/old/new와 같이 s나 '&'와 함께 사용된다.


modifier는 word designator의 뒤에 ':'를 사용하여 추가한다.


Word designator와 modifier의 사용예


• 소유자 및 그룹 변경하기


# mkdir -p /var/log/www

# chown iprize:iprize !$

chown iprize:iprize /var/log/www


• 백업 파일 만든 후 원본 파일 수정하기


$ touch important

$ cp /home/iprize/work/important !#:1_bak

cp /home/iprize/work/important /home/iprize/work/important_bak

$ ll

total 12

drwxr-xr-x 2 iprize iprize 4096 2010-08-03 22:53 ./

drwxr-xr-x 4 iprize iprize 4096 2010-08-03 22:52 ../

-rw-r--r-- 1 iprize iprize    0 2010-08-03 22:52 important

-rw-r--r-- 1 iprize iprize    0 2010-08-03 22:53 important_bak

-rw------- 1 iprize iprize  693 2010-08-03 18:41 .my_history

-rw-r--r-- 1 iprize iprize    0 2010-08-03 17:23 old

$ vi !^

vi important


 

• 디렉토리 경로 가져오기


$ ls -l /home/iprize/work/important

-rw-r--r-- 1 iprize iprize 0 2010-08-03 22:52 /home/iprize/work/important

$ cd !$:h

cd /home/iprize/work

   
• 파일명 가져오기

$ ls -l /home/iprize/work/important

-rw-r--r-- 1 iprize iprize 0 2010-08-03 22:52 /home/iprize/work/important

$ cp !$:t ~

cp important ~

$ cd

$ ls -alF

total 40

drwxr-xr-x 4 iprize iprize 4096 2010-08-03 22:58 ./

drwxr-xr-x 3 root   root   4096 2010-08-02 16:32 ../

-rw------- 1 iprize iprize  393 2010-08-03 11:54 .bash_history

-rw-r--r-- 1 iprize iprize  220 2010-08-02 16:32 .bash_logout

-rw-r--r-- 1 iprize iprize 3139 2010-08-03 22:52 .bashrc

drwxr-xr-x 2 iprize iprize 4096 2010-08-02 16:33 .cache/

-rw-r--r-- 1 iprize iprize    0 2010-08-03 22:58 important

-rw------- 1 iprize iprize   51 2010-08-03 11:55 .my_history

-rw-r--r-- 1 iprize iprize  675 2010-08-02 16:32 .profile

-rw-r--r-- 1 iprize iprize    0 2010-08-02 16:42 .sudo_as_admin_successful

-rw------- 1 iprize iprize 3208 2010-08-03 22:52 .viminfo

drwxr-xr-x 2 iprize iprize 4096 2010-08-03 22:53 work/

$


 
 참고 자료
1. history MAN page [바로가기]
2. Working with History in Bash [바로가기]


댓글 없음:

댓글 쓰기