3장. 주요 명령어들

차례

조금 더 똘똘하게 명령하기
파일시스템 관련
파일 내용 및 관리
프로세스 관리
개인정보와 권한
그 밖의 몇 가지

자주 쓰이는 명령어들에 대해서 알아보자. 가능한 한 체계적으로 분류를 해볼 것이지만 일반적인 컴퓨터 서적들과는 조금 다르게 진행할 것이다. 예를들어 대부분 문서에서 기본 명령어로 이미 소개했을 cp 명령도 아직 다루지 않았으면서, 어지간한 문서에서 한참 뒤에나 나올 몇 가지 명령을 벌써 소개했다. 어쨌든 이 순서를 충실히 잘 따라오기만 해도 우리의 목적에는[10] 충분한 것이다.

조금 더 똘똘하게 명령하기

successive / group / redirection / pipe / wildcard / historic / substitution / background

다른 명령의 긴 출력을 잘라서 보여주는 방법의 하나로 more라는 명령에 |(파이프 문자)를 써서 처리하는 경우를 보았다. 다양한 명령어들을 알아 나가기 전에 먼저, GNU/Linux 시스템에서 뿐만 아니라 일반적인 유닉스 계열 시스템에서 쉽고 요긴하게 이용할 수 있는 몇 가지 명령 요령을 알아보자. 이런 기능의 일부는 쉘에 기반한 것이고 또 일부는 쉘의 종류에 관계없는 것이지만 굳이 모든 알려진 쉘들에서 동작하는지 확인해 보진 않았음을 밝혀 둔다. GNU/Linux 시스템의 표준(?)인 Bash를 이용할 것을 추천할 뿐이다 :-)

명령어들을 활용하는 몇 가지 방식
$ command1; command2 - 명령의 연속적인 실행

어떤 명령이 끝나기를 기다렸다가 그 다음 명령을 하는 것보다 이렇게 한 번에 두 명령을 다 해버리는 게 나을 것이다. 예로 보인 것보다 더 많은 명령들도 이렇게 연속적으로 실행시킬 수 있다.

$ (command1; command2) - 명령 그룹화

위의 경우와 - 이렇게만 놓고 보면 - 아무런 차이가 없다. 하지만 이렇게 ( )로 둘러싸게 되면 마지막 명령이 끝난 후 현재의 위치로 되돌아 온다는 점이 다르다. 예를들어 cd /usr/share; ls라고 하면 /usr/share 디렉토리에 남아 있게 되지만, (cd /usr/share; ls)라고 하면 리스트를 출력한 후 다시 원래의 위치로 돌아오게 된다.

$ command > file - 입출력 방향재지정

방향재지정(redirections)은 무척 다양하게 응용할 수 있는 요령이다. 다음은 어떤 명령의 출력 결과를 그대로 새 파일에 저장하는 보기다.

$ ls / > root_fs.txt
$ more root_fs.txt
(?? 직접 해 볼 것!)

위와 같이 하면, 즉 >를 한 번만 쓰면, 원래 있던 파일의 내용이 가차없이 지워지고 새로운 출력결과가 남게 된다. (파일이 없다면 새로 만들고) 이미 존재하는 파일의 끝 부분에 추가하고 싶다면 ls >> root_fs.txt 이렇게 두 번의 화살표를 쓴다.

왼쪽으로 가는 화살표도 이용된다. 어떤 파일의 내용을 적당한 명령에 입력으로 주고 싶을 땐 command < file 이렇게 한다. 예를들어 다음은 텍스트 파일로 작성한 메시지를 전자메일에 그대로 넣어서 발송하는 보기다 ;-)

$ mail -s 'Let us have a match!' yoda@jedi.net < to.masters.txt
Cc: jedi-masters-list@jedi.net [Enter]

mail 명령에 대해서는 곧 다시 언급하겠다.

$ command1 | command2 - 파이프를 통한 입출력

파이프도 물론 여러가지로 활용할 수 있지만 지금은 간단한 세 가지 보기만 짚고 넘어가자. 너무 긴 출력을 제어하기 위해 more, less 명령과 함께 쓰이는 것은 이미 소개한 그대로다. 그리고 긴 출력화면에서 특정 문자열이 포함된 줄만 따로 걸러낼 때, 그리고 어떤 출력화면을 그대로 프린터로 보내 인쇄할 때도 아래와 같이 파이프가 쓰인다.

$ ps aux | grep jedi
(?? 역시 직접 확인할 것! 물론 jedi라는 이용자명 말고 적당한 것으로`)
$ ps aux | grep jedi | lpr

첫번재 명령은 시스템에서 동작 중인 모든 프로세스들 중, jedi라는 문자열이 포함된 경우만(다시 말해 jedi가 실행시킨) 걸러서 출력하는 것이다. 두번째 명령은 그렇게 거른 내용을 화면으로 출력하지 않고 곧바로 프린터로 출력한다. grep 명령과 lpr 명령은 다음에 소개하겠다.

$ command *.? - 와일드카드 문자 이용

이것은 파일이름을 지칭할 때 유용하다. * 문자는 모든 문자열을, 그리고 ? 문자는 하나의 문자를 의미하며 이용하는 보기는 다음과 같다.

$ ls *                      # 모든 파일을 보여준다.
$ ls ???                # 이름이 세 글자로 된 파일
$ ls *.?                # 한 글자 확장자를 갖는 모든 파일
$ ls jed*               # jed로 시작하는 모든 파일
$ ls *.c                # 확장자가 c인 모든 파일

확장자 . 문자가 유닉스 계열에서는 단지 파일명의 일부일 뿐 특별한 의미가 없음을 상기하자.

$ !! - 명령 히스토리

history라는 명령을 해보자. 와, 누가 이런 짓을?! :-o 범인은 바로 자신의 홈디렉토리에 있는 .bash_history라는 파일이다. 각자의 홈디렉토리에서 ls -a 명령으로 확인해 보자. 사용자가 내린 모든 명령들은 쉘의 임시 기억장소에 쌓여 있다가, 사용자의 로그아웃 시에 이 .bash_history 파일에 추가된다. 그리고 history 명령은 이전부터 쌓여 있는 그 파일의 내용과, 그리고 지금까지 임시 기억장소에 쌓인 내용에 번호를 붙여서 사용자의 터미널에 쏟아붓는 것이다.

!! 명령은 바로 직전의 명령을 다시 실행한다. 하나의 !에 숫자를 이어쓸 수도 있는데, 예를들어 !-3이라고 하면 세 번째 이전 명령을 다시 실행하고, !100이라고 하면 history 명령을 했을 때 100번에 해당하는 명령을 다시 실행한다.

!n 명령을 하는 것도 귀찮아하는 이용자들은 화살표키(Up, Dn)를 쓰기도 한다. 교육의 경험(?)에 비추어 볼 때 이렇게 화살표키를 이용하는 요령은 특별히 가르쳐주지 않았는데도 각자가 우연히 발견하는 듯 하다. 화살표키를 싫어하는 사람도 Ctrl-P(Previous)와 Ctrl-N(Next)로 똑같은 기능을 즐길 수 있다.

$ command2 `command1` - 출력결과 대치

` ` 문자를 이용해 어떤 명령이 아직 출력하지 않은(물론 곧 출력할) 결과를 일종의 문자열처럼 이용할 수 있다. 실제 명령이 실행되는 순서는 ` ` 안의 명령이 먼저다. 이 기능은 다음과 같이 활용할 수 있다.

$ ls ~                     # ~ 이용자의 홈; 웹페이지에서도 쓰이는 표현.
$ ls /home/`whoami`     # whoami는 말그대로 '나는 누구?'
$ gcc -o gtk_program source1.c source2.c `gtk-config --cflags` `gtk-config --libs`

처음 두 명령의 실행 결과는 동일하다. 왜 그런지는 주석문 그대로다. 세번째로 보인 예는 아마 토요일 쯤에야 의미를 알 수 있을 것이다. 하지만 gtk-config --cflags 명령이 생긴 것답지 않게 단 한 줄의 결과를 내뱉고 종료됨에 주목하자. 눈치를 챘는지? ` ` 안에 들어가는 명령은 거의 틀림없이 단 한 줄의 간단명료한 결과를 내뱉는 것들이다! 여러분 중 일부는 그 이유를 짐작하고서 음산한 미소를 머금고 있을 듯 :-)

' '가 아니라 ` `

키보드의 왼쪽 새끼 손가락에 닿는, ESC 키 아래에 있는 것이다 - 오른쪽 새끼 손가락에 닿는 단일 인용부호와 혼동하지 말 것!

$ command & - 백그라운드에서 실행

어떤 명령을 백그라운드(background)에서 실행하면 그것이 종료되기 전에 또다른 명령을 할 수 있다. 즉, 다음과 같이 곧장 쉘 프롬프트(이 상태는 다음 명령을 기다린다는 의미)가 보이기 때문이다.

$ sleep 60 &                          # 60초 동안 잔다 zzZ~
[1] 31415                               # 작업 및 프로세스 번호
$ (다른 작업을 할 수 있다...)
$ (다른 작업을 할 수 있다...)
[1]+  Done                    sleep 60  # 60초 후에 나오는 메시지

보기에 나온 sleep 명령은 아무 일도 하지 않고 빈둥거리며 시간만 재는 녀석이다. 작업과 프로세스 번호에 대해서는 다음에 더 자세히 소개될 것이다.

$ alias cmd 'long_command long_option' - 단축

쉽게 짐작할 수 있듯이 long_command long_optioncmd라고만 해서 실행시킨다. 그냥 alias라고만 하면 현재 alias된 모든 명령들이, 그리고 alias command라고 하면 그 command가 무엇으로 alias되어 있는지 보여준다.

흔히 이용하는 ls 명령을 alias ls로 확인해 보는 것이 좋은 예일 것이다. 연습삼아 unalias ls라고 한 후 ls 명령을 해보자. 물론 원래 alias된 내용으로 다시 alias를 만들수 있으므로 걱정하지 말고!

$ alias ls
alias ls='ls -sF --color=tty --show-control-chars'
$ unalias ls; ls
(뭔가 썰렁해진 출력?)
$ alias ls='ls -sF --color=tty --show-control-chars'; ls
(원래의 만족스러운 출력!)

좀 전에 배운 연속적인 명령어 실행을 이용하고 있다. 그리고 설정에 따라 이 보기와 완전히 같은 출력이 나오지 않을 수도 있다. 공백을 포함하는 문자열을 하나로 묶기 위해 작은 따옴표를 이용한다는 사실도 기억하자.

Comments - 주석문

# 문자 이후의 어떤 문자열도 쉘에서는 의미없는 주석문(단지 설명을 위해 쓰인)으로 간주된다. 예를들어 ls # -al 주석문!의 실행결과는 그냥 ls 명령과 같다.

쉘 뿐만 아니라 다른 몇 가지 언어에서의 주석문도 상식삼아 알아두자. C/C++/Java 등 프로그래밍 언어에서는 // 오른쪽의 모든 문자열, 그리고 /**/ 사이의 모든 문자열이 주석문이다. 그리고 HTML/SGML/XML 등 거의 모든 마크업 언어(*ML)에서는 <!----> 사이의 모든 문자열이 주석으로 처리된다.



[10] 우리가 이 스터디를 진행하는 목적은 물론 GNU/Linux 시스템에서 전산물리를 - 또는 자신의 어떤 관심 사항을 - 공부할 수 있는 최소한의 교양을 익히는 것이다.