티스토리 뷰

윈도우에 질려 리눅스로 넘어온 대부분의 사용자들이 가장 불편하게 느끼는 부분이 바로 터미널에 대한 높은 의존도일 것이다. 리눅스의 높은 진입장벽은 그렇게 만들어진다. 사실 요즘 세상이 좋아져서 리눅스도 윈도우 뺨치는 GUI 가 많이 등장했지만 우리가 리눅스를 사용하는 근본적인 이유는 시스템의 모든 것을 스마트하게 제어할 수 있는 터미널의 존재 때문이니 GUI 는 중요하지 않다. (윈도우에는 command 가 터미널의 역할을 수행한다고 할 수 있다.) 어느정도 터미널을 익숙하게 사용할 수 있게되면 그때부터는 그 매력에서 빠져나오지 못할 것이다.

터미널을 사용한다는 것은 다양한 shell 을 통해 시스템의 환경을 설정하고 조작하는 것을 의미하겠다. shell 은 시스템 제어와 모니터링을 위한 다양한 명령어를 사용할 수 있는데 여기서는 딱 세가지, find, grep, awk 를 다루고자 한다. 이 세가지를 다루는 궁극적인 이유는 파이프라인(|)을 통한 명령어 조합에 있다. 특히 grep 이나 awk 는 여러가지 명령어에 이어 붙여 강력하게 활용될 수 있다. 서론이 길었으니 명령어의 기본 옵션과 다양한 예제를 통해 실습 해보고 명령어를 이해하도록 해보자.

find


find 는 한마디로 윈도우의 탐색기를 터미널 명령어로 옮겨놨다고 이해하면 된다. 아니, 그것보다 훨씬 우수하다. 특정 확장자를 뽑아내거나 일정 사이즈 이상의 파일만 검색하는 등의 모든 검색이 된다. 찾고자 하는 대부분을 find 명령 하나로 쉽게 찾을 수 있을 것이다. SQL 쿼리를 생각해보자. 적재되어 있는 데이터를 다양한 방식으로 원하는 모든 것을 뽑아낼 수 있지만 막상 쿼리문을 모르면 뽑아낼 수 없지 않는가? 좋은 칼이지만 잘 다룰때 비로소 빛을 본다는 이야기다. 아래 몇 가지 예제를 익히면 터미널에서 다양하게 응용할 수 있을 것이다.

root 경로의 모든 파일, 링크, 소켓, FIFO, 디렉터리등 모든 것을 출력
$ find /

root 경로에서 "파일"만 출력
$ find / -type f

root 경로에서 "디렉터리"만 출력
$ find / -type d

root 경로의 "파일" 중 size 가 5M 이상인 것만 출력 (k,M,G,T,P 로 단위 구분, +- 로 이상,이하 구분)
$ find / -type f -size +5M

root 경로의 "파일' 중 size 가 5M 이상이고 권한이 644 인 것만 출력
$ find / -type f -size +5M -perm 644

644 앞에 +,- 를 붙이기도 하는데 +는 포함하는 모든것을, -는 일부라도 포함하는 것을 의미한다. 한편 +, -가 없는 것은 완전히 일치하는 퍼미션만 찾게된다.

root 경로의 "파일" 중 size 가 5M 이상이고 파일의 상태가 변경된지 5일 이상 된 것을 찾는다. (s,m,h,d,w 를 단위로 구분, 이는 초,분,시,일,주를 나타낸다.)
$ find / -type f -size +5M -mtime +5d

이때 mtime 은 파일의 modify 를 의미하고, atimeaccess, ctime 는 파일의 상태가 change 된 것을 나타내는데 사용된다.

지금까지는 단순히 무엇인가 찾기만 하는데 find 명령어를 사용했는데 아래는 찾은 결과에 서브 명령을 실행시키는 형태이다. 이제 본격적이다. 

root 경로의 "파일"중 size 가 5M 이상인 것만 출력하는데 ls 의 형태로 출력
$ find / -type f -size +5M -exec ls -l {} \;

이번에는 exec 라는 재밌는 옵션이 추가되었는데 뒤에 명령어를 이어붙일 때 사용된다. 위 예제의 경우에는 find 에서 나온 결과에 ls 를 이어붙였다. {} find 에서 나온 각각의 결과를 의미하는 변수 같은 개념이다. 예를들어 find 의 결과로 aa, bb, cc 라는 파일이 출력되었다면 {} 에는 aa, bb, cc 가 각각 들어가게 된다.  끝으로 \; 는 정상적으로 모든 exec 의 모든 실행이 끝났다는 것을 find 에게 알려주는 역할을 한다. 정리하면 위 명령어는 파일의 사이즈가 5M 이상되는 것을 ls 옵션으로 상세하게 출력하는 것을 의미한다. 조금 다른 예를 들자면 아래는 어떨까?
$ find / -type f -size +5M -exec rm -rf {} \;

조금 살벌한 느낌이 오는가? root 경로 밑에 5M가 넘는 파일은 모두 삭제하겠다는 소름 돋는 명령이다. 

이외에도 find 는 다양한 옵션을 통해 사용자가 원하는 거의 모든 것을 찾는데 도움을 준다. 리눅스를 다루는 사람이라면 언급한 옵션 정도는 기본으로 숙지하도록 하고 이외의 옵션은 플러스로 익히는게 좋겠다. (goto man find)

grep


grep 은 파일이나 표준입력(stdin) 으로부터 패턴을 찾아주는 역할을 한다. 쉽게 이야기하면 파일의 내용이나 콘솔에 출력물 중에 특정 문자열을 찾는데 널리 사용될 수 있으니 그 중요도가 리눅스 명령어 내에서 탑 클래스 안에 든다고 해도 과언이 아니다. 바로 예제를 살펴보자.

test.txt 파일에서 foo 라는 문자열이 있는 라인을 찾아서 출력한다.
$ grep foo test.txt

현재 경로의 모든 파일에서 foo 라는 문자열이 있는 라인을 찾아서 출력한다.
$ grep foo *

현재 경로와 하위에 있는 모든 파일에서 foo 라는 문자열이 있는 라인을 찾아서 출력한다. (--recursive)
$ grep foo * -r 

test.txt 파일에서 foo 라는 문자열이 있는 라인을 찾아서 출력하는데 바로 다음 3라인을 함께 출력한다. (셸 포럼에 자주 등장하는 질문이다.)
$ grep foo test.txt -A 3

test.txt 파일에서 foo 라는 문자열이 있는 라인을 찾아서 라인번호와 함께 출력한다.
$ grep foo test.txt -n

현재 경로와 하위에 있는 모든 파일에서 foo 라는 문자열이 있는 라인을 라인번호와 함께 출력한다.
$ grep foo * -rn

test.txt 파일에서 foo 라는 문자열이 있는 라인을 찾아서 출력하는데 foo 라는 문자열에는 색상을 입혀서 출력한다.
$ grep foo test.txt --color=auto

아래부터는 표준입력을 통한 사용법이다. 위에서 사용된 옵션은 모두 동일하게 사용할 수 있다. 단지 패턴을 찾는 대상이 파일에서 표준입력이 된 것 뿐이다. 

ps 의 결과에서 foo 가 있는 라인을 출력한다.
$ ps aux | grep foo

ps 의 결과에서 foo 가 있는 라인을 최대 3개만 출력한다.
$ ps aux | grep foo -m 3

ps 의 결과에서 foo 가 있는 라인을 출력하는데 결과에서 bar 는 빼고 출력한다.
$ ps aux | grep foo | grep -v 'bar'

위의 예제를 보면 알 수 있겠지만 grep 은 파일 내에 변수나 함수 등 문구를 찾을 때 자주 사용되며 한편으로는 어떤 실행 결과로부터 문자를 파싱하기 위한 용도로 많이 사용된다. 사용에 익숙해지다보면 옵션에서 약 2% 정도 아쉬움을 느낄 수 있는데 grep 을 발전시킨 egrep (extended grep) 등도 있으니 숙지하면 좋다. 요즘이야 egrep도 웬만한 *NIX 머신에 기본 built-in 되어 나오지만 오래된 버전의 커널을 사용하는 on-premise 의 경우 그렇지 않은 경우도 있으니 참고하도록 하자.

awk


awk 는 사실 여기서 다룬다는 것 자체가 모순일 정도로 방대한 분량을 갖고 있다. 명령어라고 칭하고 있기는 하지만 사실 스크립트 언어기 때문이다. 그렇기 때문에 그 활용도가 엄청나지만 기본적으로 자주 사용되는 몇 가지만 숙지하도록 하자. 기본적으로 awkgrep 과 마찬가지로 표준입력이나 파일로부터 입력을 받고 문자를 파싱해서 원하는 결과를 얻어내는데 사용된다. 아래 예제를 살펴보자.

ps 의 결과 중에 1열(세로줄, cloumn)을 출력한다.
$ ps aux | awk '{print $1}'

ps 상에 보이는 모든 명령어의 uid 를 전부 출력한다고 생각하면 된다. 아래처럼 pid 까지 함께 출력할 수도 있다.
$ ps aux | awk '{print $1,$2}'

1부터 10까지 더하는 것도 가능하다. 아래는 많은 값을 뽑아낸 이후에 값의 합을 계산할 때 주로 사용하는 방법에 대한 예제이다.
$ seq 1 10 | awk '{s+=$1} END {print s}'

위에서 나온 것을 응용해서 특정 프로세스의 VmRSS 를  주기적으로 출력하는 스크립트를 돌려보자. 주로 데몬을 개발하면서 메모리를 모니터링할 때 사용되는 스크립트다. 종종 데몬이 down/up 되어도 모니터링은 계속된다.
$ while [ 1 ];do cat /proc/$(ps aux | grep syslogd | grep -v grep | awk '{print $2}')/status | grep VmRSS;sleep 1;done

응용분야는 매우 다양하기 때문에 모두 예로 들 수 없다. 분명한건 무엇인가 터미널에서 파싱하고자 한다면 grepawk, 단 두개면 충분하다는 것이다. 이 글이 두 명령어를 익히고 리눅스와 약간은 친해질 수 있는 계기가 되기를 바란다.



댓글
최근에 올라온 글
최근에 달린 댓글
글 보관함
Total
Today
Yesterday