전형적인 유닉스(UNIX®) 관리자라면 시스템을 관리하면서 나름대로 자주 사용하는 유틸리티, 스크립트, 기교가 있기 마련이다. 이러한 유틸리티, 스크립트, 명령 체인 등은 관리자가 수행할 작업을 단순화시켜준다. 일부 도구는 운영체제에 딸려오지만, 대다수 도구와 기교는 수년동안 쌓아온 경험과 시스템 관리를 조금이라도 편하게 하려는 욕구에서 비롯했다. 이번 연재물은 다양한 유닉스 환경에서 제공하는 도구를 최대한 활용하는 방법을 살펴본다. 또한 다양한 유닉스 플랫폼에서 일관성있는 방식으로 시스템을 관리하는 방법도 소개한다.
ps 명령은 현재 시스템에서 돌아가는 프로세스를 열거한다. 유닉스 계열 운영체제는 모두 ps 명령을 제공하며, 기본적으로 명령이 동작하는 방식도 같다. 즉, ps 명령은 현재 돌아가는 프로세스 목록을 커널에 요청하여 프로세스 목록과 각 프로세스 속성을 출력한다. 프로세스 속성으로는 메모리 사용량, 실행 시간 등이 있다.
많은 관리자들이 대개 원하는 정보를 뽑아내기 위해 한두 가지 옵션만을 사용하지만, 사실 ps 명령은 매우 강력한 유틸리티다. 명령 자체가 제공하는 내장 옵션이 매우 다양할 뿐만 아니라, ps 명령과 그 외 명령을 파이프로 연결해 원하는 정보를 정확히 추출할 수도 있다.
옵션을 지정하지 않고 ps 명령을 수행하면 현재 사용자가 실행 중인 프로세스 목록을 표준 출력으로 내보낸다. 루트로 로그인하는 경우도 마찬가지다. 시스템에 있는 다른 프로세서에 대한 정보가 필요하거나 정보가 출력되는 형식을 바꾸려면 (BSD, AT&T, SVR 등) 유닉스 계열에 따라서 명령행 옵션을 다르게 주어야 한다. 기본적으로 BSD 유닉스 계열에서 ps 명령을 실행하면 프로세스 ID, 터미널, 상태, 시간(초), 실행 명령이 출력된다. 여기서 시간은 프로세스를 시작한 시간이 아니라 프로세스가 사용한 CPU 시간이다. Listing 1은 BSD 유닉스 계열에서 ps 명령을 실행한 결과다.
Listing 1. BSD 유닉스 계열에서 사용자 프로세스 목록 보기
$ ps
PID TT STAT TIME COMMAND
391 p5 S 0:00.24 /bin/bash
9165 p5 S+ 0:00.50 emacs
476 p6 S 0:01.03 /bin/bash
9299 p6 S 0:00.09 xterm
9319 p6 S 0:00.07 xterm
9423 p6 S 0:00.12 ftp atuin
9513 p6 R+ 0:00.01 ps
9301 p7 Ss+ 0:00.01 /usr/X11R6/bin/luit
9302 p8 Ss+ 0:00.03 bash
9321 p9 Ss+ 0:00.01 /usr/X11R6/bin/luit
9322 pa Ss+ 0:00.02 bash
|
SVR4 계열에서는 출력되는 정보가 더 간략하다. Listing 2에서 보듯이, 프로세스 상태가 출력되지 않는다.
Listing 2. SVR4 유닉스 계열에서 사용자 프로세스 목록 보기
$ ps
PID TTY TIME CMD
19915 pts/3 00:00:00 bash
29145 pts/3 00:00:00 emacs
32256 pts/3 00:00:00 emacs
26986 pts/3 00:00:00 xterm
31303 pts/3 00:00:00 ftp
31358 pts/3 00:00:00 ps
|
시스템에서 돌아가는 프로세스 전체 목록을 얻으려면 명령행 옵션을 지정한다. 물론 유닉스 계열에 따라서 옵션이 달라진다. BSD 계열에서 (명령 자신을 포함하여) 모든 사용자 프로세스 목록을 출력하려면 -a 옵션을 사용한다. 하지만 이 옵션은 제어 터미널이 없는 프로세스를 포함하지 않는다. 즉, 데몬, 시스템을 시작할 때 수행되는 프로세스, cron으로 수행되는 프로세스 등은 출력하지 않는다. 이러한 프로세스까지 모두 포함하려면 -A 옵션을 사용한다(Listing 3 참조).
Listing 3. BSD 유닉스 계열에서 전체 프로세스 목록 보기
$ ps -A
PID TT STAT TIME COMMAND
1 ?? S<s 0:15.47 /sbin/launchd
23 ?? Ss 0:00.02 /sbin/dynamic_pager -F /private/var/vm/swapfile
27 ?? Ss 0:00.95 kextd
49 ?? Ss 0:05.17 /usr/sbin/configd
50 ?? Ss 0:01.89 /usr/sbin/coreaudiod
51 ?? Ss 0:04.40 /usr/sbin/diskarbitrationd
52 ?? Ss 0:00.08 /usr/sbin/memberd -x
53 ?? Ss 0:02.80 /usr/sbin/securityd
55 ?? Ss 11:03.59 /usr/sbin/notifyd
57 ?? Ss 0:01.13 /usr/sbin/DirectoryService
...
8051 p2 S+ 0:00.61 ssh root@bear
292 p3 Ss 0:00.02 bash
372 p3 S+ 0:00.42 ssh admin@atuin
312 p4 Ss+ 0:00.03 bash
332 p5 Ss 0:00.03 bash
391 p5 S 0:00.24 /bin/bash
9165 p5 S+ 0:00.50 emacs
352 p6 Ss 0:00.04 bash
476 p6 S 0:01.04 /bin/bash
9299 p6 S 0:00.09 xterm
9319 p6 S 0:00.07 xterm
9423 p6 S 0:00.14 ftp atuin
9520 p6 R+ 0:00.01 ps -A
9301 p7 Ss+ 0:00.01 /usr/X11R6/bin/luit
9302 p8 Ss+ 0:00.03 bash
9321 p9 Ss+ 0:00.01 /usr/X11R6/bin/luit
9322 pa Ss+ 0:00.02 bash
|
-A 명령행 옵션은 -a와 -x 옵션과 동일하다. 여기서 -a는 제어 터미널이 있는 프로세스 목록을 출력하고, -x는 제어 터미널이 없는 프로세스 목록을 출력한다.
SVR4 계열에서 모든 프로세스를 출력하려면 -e 옵션을 사용한다. -e 옵션은 제어 터미널이 있는 프로세스와 없는 프로세스를 모두 출력한다. BSD 계열에서 제공하는 -A 옵션과 같다. Listing 4는 SVR4 계열에서 모든 프로세스를 출력한 결과다.
Listing 4. SVR4 유닉스 계열에서 전체 프로세스 목록 보기
$ ps -e
PID TTY TIME CMD
0 ? 15:24 sched
1 ? 0:00 init
2 ? 0:00 pageout
3 ? 0:00 fsflush
308 ? 0:00 devfsadm
7 ? 0:06 svc.star
9 ? 0:10 svc.conf
506 ? 0:00 htt_serv
260 ? 0:00 rpcbind
259 ? 0:00 cron
52 ? 0:00 dhcpagen
282 console 0:00 ttymon
267 ? 0:00 lockd
264 ? 0:00 statd
90 ? 0:00 sysevent
...
462 ? 0:00 smcboot
464 ? 0:00 smcboot
463 ? 0:00 smcboot
473 ? 0:00 htt
552 ? 0:00 in.telne
527 ? 0:00 dmispd
548 ? 0:01 snmpd
|
위에서 보듯이, Listing 3과 Listing 4는 출력되는 열 개수가 다르다. 하지만 필요하다면 언제든 원하는 열을 지정해 출력할 수도 있다.
ps 도구가 표준으로 제공하는 정보는 다양하다. 예를 들어 SVR4 계열에서 흔히 사용하는 ps -ef 명령은 부모 프로세스 ID, CPU 사용량, 시작 시간 등 자세한 정보를 제공한다. Listing 5는 SVR4 계열에서 ps -ef 명령을 실행한 결과다.
Listing 5. SVR4 유닉스 계열에서 좀 더 상세한 정보 보기
ps -ef
UID PID PPID C STIME TTY TIME CMD
root 0 0 0 15:56:26 ? 15:24 sched
root 1 0 0 15:56:26 ? 0:00 /sbin/init
root 2 0 0 15:56:26 ? 0:00 pageout
root 3 0 0 15:56:26 ? 0:00 fsflush
root 308 1 0 15:57:09 ? 0:00 devfsadmd
root 7 1 0 15:56:29 ? 0:06 /lib/svc/bin/svc.startd
...
root 562 1 0 15:58:17 ? 0:00 /usr/lib/sendmail -bd -q15m
root 576 555 1 16:01:47 pts/1 0:00 ps -ef
root 416 1 0 15:57:14 ? 0:00 /usr/sbin/syslogd
smmsp 561 1 0 15:58:17 ? 0:00 /usr/lib/sendmail -Ac -q15m
...
root 552 283 0 15:57:47 ? 0:00 /usr/sbin/in.telnetd
root 527 1 0 15:57:22 ? 0:00 /usr/lib/dmi/dmispd
root 548 1 0 15:57:24 ? 0:01 /usr/sfw/sbin/snmpd
|
BSD 계열에서는 보통 -l 옵션을 추가한다. 여기서 l은 "long"을 뜻한다. Listing 6은 BSD 계열에서 ps -al 명령을 실행한 결과다.
Listing 6. BSD 유닉스 계열에서 좀 더 상세한 정보 보기
$ ps -al
UID PID PPID CPU PRI NI VSZ RSS WCHAN STAT TT TIME COMMAND
0 9165 391 0 31 0 57896 6376 - S+ p5 0:00.50 emacs
501 352 349 0 31 0 27784 52 - Ss p6 0:00.04 bash
0 476 352 0 31 0 27784 600 - S p6 0:01.05 /bin/bash
0 9299 476 0 31 0 44988 1880 - S p6 0:00.09 xterm
0 9319 476 0 31 0 44988 1888 - S p6 0:00.07 xterm
0 9423 476 0 31 0 27504 488 - S p6 0:00.15 ftp atuin
0 9540 476 0 31 0 27384 504 - R+ p6 0:00.01 ps -axl
0 9301 9299 0 31 0 27332 452 - Ss+ p7 0:00.01 /usr/X11R6/bin/luit
0 9302 9301 0 31 0 27784 888 - Ss+ p8 0:00.03 bash
0 9321 9319 0 31 0 27332 452 - Ss+ p9 0:00.01 /usr/X11R6/bin/luit
0 9322 9321 0 31 0 27784 888 - Ss+ pa 0:00.02 bash
|
Listing 5와 Listing 6에서 살펴본 옵션은 확실히 많은 정보를 출력한다. 하지만 정보가 많다고 무조건 바람직하지는 않다. 관리자가 특정한 정보를 원한다면 나머지 정보가 오히려 부담스러울 수도 있다.
다행스럽게도 ps 명령은 출력할 열을 지정할 수 있다. 즉, 유닉스 계열이 달라도 동일한 결과를 표준화된 형식으로 얻어낼 수 있다는 뜻이다.
출력할 열을 지정하려면 -o 옵션을 사용한다. -o 옵션 뒤에 원하는 열 이름을 추가하면 된다. 여러 열을 출력하려면 각 열 이름을 쉼표로 분리한다. 유닉스 계열마다 지원되는 열 종류는 약간씩 차이가 있지만, 대다수 열이 표준으로 지원된다. 예를 들어 pid, ppid(부모 pid), 명령, RSS(Resident Set Size 또는 메모리 사용량), 우선순위는 모든 유닉스 환경에서 제공한다.
-o 옵션 뒤에 열 이름을 지정할 때는 출력하려는 순서대로 지정한다. 예를 들어 BSD 계열에서 pid, ppid, 명령 열을 출력하려면 -opid,ppid,command라고 지정한다. SVR4 계열에서는 -opid,ppid,comm라고 지정한다. Listing 7과 Listing 8은 각각 BSD 유닉스 계열과 SVR4 유닉스 계열에서 명령을 실행한 결과다.
Listing 7. BSD 유닉스 계열에서 열 지정하기
$ ps -o pid,ppid,command
PID PPID COMMAND
391 332 /bin/bash
9165 391 emacs
|
Listing 8. SVR4 유닉스 계열에서 열 지정하기
$ ps -opid,ppid,comm
PID PPID COMMAND
555 552 -sh
622 555 ps
|
이제 원하는 열을 찾아냈으니, 이번에는 원하는 순서로 정보를 정렬해 보자. 기본적으로 ps 명령은 프로세스 ID 값으로 목록을 정렬하지만 이는 찾고자 하는 정확한 정보를 가려버릴지도 모른다. 만약 메모리가 부족한 프로세스를 찾고 싶다면 프로세스 ID로 정렬된 목록보다 메모리 사용량으로 정렬된 목록이 훨씬 더 유용하다.
일부 ps 버전은 별도로 명령행 옵션을 제공한다. 예를 들어 BSD 계열에서는 -m 옵션과 -r 옵션이 존재하는데, -m 옵션은 메모리 사용량 순으로 목록을 정렬하고, -r 옵션은 CPU 사용량 순으로 목록을 정렬한다. 대다수 SVR4 계열은 별다른 옵션을 제공하지 않는다. 하지만 두 계열 모두 ps와 sort를 조합해 원하는 결과를 얻어낼 수 있다. 예를 들어 BSD 계열에서 CPU 사용량에 따라 프로세스 목록을 정렬하려면 Listing 9와 같은 명령을 실행한다.
Listing 9. BSD 유닉스 계열에서 CPU 사용량 추적하기
$ ps -A -o pid,%cpu,command|sort -n +1
...
358 0.1 ftp
11425 0.1 /bin/bash
28684 0.3 trivial-rewrite -n rewrite -t unix -u
356 0.4 ssh
354 0.5 as
23988 1.1 emacs
136 14.6 cc1plus
26306 23.6 cpp
|
SVR4 계열에서는 pcpu가 %cpu로 변할 뿐 나머지 부분은 같다. Listing 10을 참조한다.
Listing 10. SVR4 유닉스 계열에서 CPU 사용량 추적하기
$ ps -e -opid,pcpu,comm|sort -n +1
...
3 0.1 fsflush
555 0.1 -sh
627 0.2 sort
628 0.2 ps
|
위 명령 체인은 정말로 필요한 정보를 얻기 위해 열 이름으로 프로세스 목록을 찾은 후 특정한 열에 따라 목록을 정렬한다. 열 이름이 아니라 다른 조건으로 프로세스 목록을 찾으려면 다음 방법을 사용한다.
동작 중인 프로세스 목록을 찾아냈다면, 분명히 특정 프로세스를 찾아내야 할 경우가 생긴다. 정확하게 원하는 정보만 뽑아내는 가장 간단한 방법은 ps와 grep 명령 조합이다. 일부 유닉스 계열은 pgrep 같이 별도 유틸리티를 제공하지만, 일반적으로 그냥 grep을 사용해도 전혀 문제가 없다.
$ ps -ef|grep bash |
ps 명령 자체에서 프로세스를 보기 위해 옵션으로 특정 조건을 지정하는 방법도 있다. 사용자 ID, 부모 프로세스, 제어 터미널 등은 ps 도구에서 구체적인 옵션을 제공한다. 예를 들어 -U 옵션은 특정한 사용자가 소유하는 프로세스 목록을 출력한다. Listing 11은 현재 root가 소유하는 프로세스 목록이다.
Listing 11. 사용자가 소유하는 프로세스 보기
$ ps -U root
PID TTY TIME CMD
0 ? 15:24 sched
1 ? 0:00 init
2 ? 0:00 pageout
3 ? 0:02 fsflush
308 ? 0:00 devfsadm
7 ? 0:06 svc.star
...
552 ? 0:00 in.telne
527 ? 0:00 dmispd
629 pts/1 0:00 ps
548 ? 0:01 snmpd
|
특정한 터미널에서 수행한 프로세스 목록을 보려면 -t 옵션을 사용한다. Listing 12를 참조한다.
Listing 12. 특정한 터미널에서 수행한 프로세스 보기
$ ps -t 3
PID TTY TIME CMD
19915 pts/3 00:00:00 bash
29145 pts/3 00:00:00 emacs
32256 pts/3 00:00:00 emacs
|
이제까지 다양한 방법으로 원하는 프로세스를 찾아냈다. 이제 찾아낸 프로세스를 제어하는 방법을 살펴보자.
원하는 프로세스를 찾은 후 가장 흔히 사용하는 프로세스 제어 명령은 kill이다. kill 명령은 프로세스에 특정한 시그널을 보낸다. 데몬에 여러 스레드나 여러 자식 프로세스가 존재한다면 부모 프로세스에 시그널을 보내서 나머지 프로세스로 전달할 수도 있다. 하지만 이와 같은 방식으로 동작하지 않는 데몬과 응용 프로그램도 존재한다.
프로세스를 수작업으로 찾아내어 하나씩 죽이는 방법도 있지만 시간이 걸리고 번거롭다. 그래서 일부 유닉스 계열은 pkill이라는 명령을 제공한다. pkill은 특정한 패턴이나 조건에 만족하는 프로세스 전부에 시그널을 보낸다. 예를 들어 터미널, 프로세스 그룹, 사용자 ID, 그룹 ID를 지정하여 해당하는 프로세스 전부에 시그널을 보낼 수 있다.
pkill이라는 명령이 없다면 ps, grep, awk, xargs, kill 명령을 조합해 특정한 패턴에 만족하는 프로세스 전부에 시그널을 보내도 된다. 예를 들어 명령 열에 "httpd"라는 문자열이 들어 있는 프로세스 전부에 kill 시그널을 보내려면 다음 명령 체인을 사용한다.
$ ps -e -opid,command |grep httpd|awk '{print $1}'|xargs kill -9
|
위 명령 체인을 하나씩 뜯어서 분석해보자.
$ ps -e -opid,command |
SVR4 계열에서 위 명령은 현재 실행 중인 프로세스 전부를 열거한다. 앞서 설명했듯이, BSD 계열이라면 -A를 사용한다. -o 옵션으로 출력할 열을 지정했으므로 프로세스 ID와 실행 명령 두 개만 출력된다. 여기서 다른 열은 필요하지 않다. 다른 열까지 출력했다가는 (다른 열에 혹시라도 httpd가 들어 있는 경우) 다음으로 수행할 grep이 잘못된 결과를 내놓을지도 모른다.
$ ps -e -opid,command |grep httpd |
위 명령은 명령 열에 httpd가 들어 있는 프로세스를 추출한다. 파이프 앞에 있는 명령에서 프로세스 ID와 명령 열만 출력하므로 (프로세스 ID는 숫자이므로) grep은 명령 열만 검색하는 셈이다.
$ ps -e -opid,command |grep httpd|awk '{print $1}'
|
다음으로 awk 명령을 사용하여 첫 번째 인수인 프로세스 ID만 걸러낸다.
$ ps -e -opid,command |grep httpd|awk '{print $1}'|xargs kill -9
|
xargs 명령은 공백으로 분리된 목록을 받아서 목록 내 각 항목에다 인수로 주어진 명령을 실행한다. 즉, 프로세스 ID 목록을 받아서 각 프로세스 ID에다 kill -9 명령을 실행한다. 여기서 공백이란 복귀 문자, 개행 문자, 탭, 여러 공백을 모두 포함한다.
위 명령 체인을 스크립트로 저장하면 편리하다. 스크립트 이름은 pkill이나 killbyname 정도면 적당하겠다. Listing 13에서 구현한 스크립트는 1) 프로세스로 보내려는 시그널과 2)프로세스를 검색할 패턴을 인수로 받는다. 그런 다음, 해당 패턴에 만족하는 프로세스 각각에 인수로 해당 시그널을 보낸다. Listing 13에서는 유닉스 계열까지 고려하여 적절한 명령을 수행한다.
Listing 13. 명령 하나로 여러 프로세스 죽이기
#!/bin/sh
HOSTTYPE=`uname -s`
SIGNAL=$1
STRING=$2
if [ -z "$1" -o -z "$2" ]
then
echo Usage: $0 signal string
exit 1
fi
case $HOSTTYPE in
Darwin|BSD)
ps -a -opid,command | grep $STRING | awk '{ print $1; }' | xargs kill $SIGNAL
;;
Linux|Solaris|AIX|HP-UX)
ps -e -opid,command | grep $STRING | awk '{ print $1; }' | xargs kill $SIGNAL
;;
esac
|
다른 목적으로 프로세스를 찾을 때도 위와 비슷한 기법을 적용할 수 있다.
앞서 언급하지 않았지만, ps 명령은 두 가지 유용한 정보를 제공한다. 하나는 RSS(Resident Set Size)라는 정보인데, 이는 프로세스가 차지하는 물리적 메모리 양을 뜻한다. 현재 프로세스가 사용 중인 실제 메모리 양을 짐작하기에 좋은 정보다. 다른 하나는 VSZ라는 정보인데, 이는 프로세스가 차지하는 내부 저장소와 외부 스왑 디스크를 포함한 총 가상 메모리 양을 뜻한다. 대다수 ps 버전이 두 가지 정보 모두를 제공한다.
RSS와 VSZ 정보를 살펴보면 프로세스가 사용하는 메모리 양을 가늠하기 쉽다. 특정한 응용 프로그램이나 특정 프로그램과 그 자식 프로세스가 사용하는 물리적 메모리와 가상 메모리를 살펴보려면 ps와 grep으로 프로세스를 선택한 다음 awk로 총합을 계산한다.
예를 들어 Listing 14는 bash 프로세스가 사용하는 물리적 메모리 양과 가상 메모리 양을 합한 결과다.
Listing 14.
ps와 awk로 메모리 사용량 계산하기
$ ps -A -o rss,vsz,command|grep bash | \
awk '{rss += $1; vsz += $2 } END { print "Real: ",rss, "Virtual: ",vsz }'
Real: 4004 Virtual: 305624
|
위와 같은 정보는 메모리 사용량 문제와 스왑 공간 사용량 문제를 진단할 때 특히 유용하다.
일반적인 시스템 관리자라면 한 번에 여러 작업을 동시에 수행하는 경우가 아주 흔하다. (xterm을 사용하든, SSH를 사용하든, telnet을 사용하든) 동시에 한 서버로 여러 세션을 연결해서 열어놓았더라도 현재 사용 중인 셸 하나에서 여러 프로세스를 관리하거나 제어할 필요가 생긴다.
모든 셸은 명령을 백그라운드에서 자동으로 실행하는 기능을 제공한다. 명령을 실행할 때 가장 마지막에 & 기호를 붙이면 된다. 그런데 때로는 사용자 입력이 필요한 응용 프로그램, 예를 들어 편집기 같은 프로그램을 일시적으로만 백그라운드로 실행할 필요가 생긴다. 편집기를 백그라운드로 돌린 다음, 셸 명령을 실행한 후, 편집기 세션으로 되돌아오기 위해서다.
이러한 방식으로 백그라운드 프로세스를 제어하는 기능을 작업 제어(job control)라고 한다. Korn 셸, C 셸이나 (bash 셸, zsh 셸과 같은) 오픈 소스 셸에서 표준으로 제공하는 기능이다.
셸에서 기본적인 작업 제어 기능이 동작하는 방식은 간단하다. 사용자가 명령을 백그라운드로 실행하면, 셸은 해당 명령에 작업 참조 ID(job reference ID)를 할당한다. 여기서 백그라운드로 실행하려는 명령은 인라인 스크립트를 포함하여 어떤 명령도 가능하다.
$ find / -name "core" >/tmp/corelist 2>&1 & [3] 11957 |
백그라운드로 실행 중인 프로세스는 jobs 명령으로 확인한다. Listing 15를 참조한다.
Listing 15.
jobs 명령 사용하기
$ jobs
[1]- Stopped emacs MCSLP/Intranet/News.pm
[2]+ Stopped emacs MCSLP/Intranet/Media.pm
[3] Running find / -name "core" >/tmp/corelist 2>&1 &
|
Listing 15에서 두 번째 emacs 명령 앞에는 + 기호가 붙어 있다. 현재 셸이 emacs를 활성 작업으로 간주한다는 뜻이다. 직전에 수행한 find 명령은 활성 작업이 아니다. 결과는 출력했지만 입력이 필요하지 않으므로 활성 프로세스가 되지 못한다. 첫 번째 emacs 프로세스 앞에는 -- 기호가 붙어 있다. 이는 이전에 활성 명령이었다는 뜻이다. 각 작업을 참조할 때는 각각 %+와 %- 문자열을 사용한다.
백그라운드 작업을 포그라운드로 전환하려면 fg 명령 다음에 작업 번호를 지정한다. 작업 번호 대신 작업 문자열(%+, %-)을 사용해도 좋다. 작업 번호나 작업 문자열을 지정하지 않으면 셸은 현재 활성 작업을 포그라운드로 전환한다.
현재 실행 중인 프로세스를 일시적으로 멈추려면 Control-Z를 누른다. 다음과 같은 모습이 된다.
ftp> [3]+ Stopped ftp atuin |
Control-Z는 대다수 명령과 응용 프로그램에서 먹힌다. ls나 find 등 셸에서 실행하는 간단한 명령 대다수에도 통한다. 여기서 작업은 Stopped 상태가 된다는 사실에 주의한다. 즉, 명령 실행이 일시적으로 중단되었다는 뜻이다. 중단된 명령을 백그라운드 프로세스로 전환하려면 bg 명령을 사용한다. fg 명령과 마찬가지로 bg 명령 역시 작업 참조 ID를 인수로 받는다. 작업 참조 ID를 지정하지 않으면 현재 활성 작업을 백그라운드로 전환한다. 편집기나 FTP 등 사용자 입력이 필요한 명령을 bg 명령을 사용해서 백그라운드로 전환하면 프로세스가 일시적으로 중단되었다는 경고 메시지가 뜬다. Listing 16을 참조한다.
Listing 16. 프로세스가 일시적으로 중단되었다는 경고
$ bg
[3]+ ftp atuin &
$
[3]+ Stopped
|
작업 제어를 통해 백그라운드로 전환한 명령이 결과를 출력한다면, 별도로 출력 위치를 재지정하지 않는 한, 결과는 화면으로 출력된다.
관리자가 수행하는 작업이 많은 경우 작업 제어 기능은 여러 백그라운드 작업을 관리하고 통제하기 가장 좋은 방법이다. (셸을 새로 띄울 필요 없이) 편집기를 재빨리 빠져나가 필요한 명령을 수행한 후 활성 작업으로 되돌아오면 된다.
때때로 백그라운드에서 스크립트, 유틸리티, 명령행 등을 실행할 필요가 생긴다. 하지만 대다수 시스템은 사용자가 연결을 끊거나 로그아웃하면 백그라운드 프로세스를 종료시킨다. 즉, 로그인해서 명령을 시작한 다음 로그아웃하기를 원하는 여러분 의도에 반해서 동작한다는 말이다.
스스로 데몬화하지 못하는 프로세스를 데몬으로 실행하거나 백그라운드로 돌리려는 경우에 로그아웃하자마자 프로세스가 죽어버리면 참으로 난감하다. 로그인해서 특정한 스크립트를 실행해야만 데몬이 되는 프로세스도 마찬가지다. MySQL의 mysqld_safe 스크립트가 좋은 예다.
로그아웃 시 응용 프로그램이 자동으로 종료되지 않게 하려면 nohup 명령을 사용한다. 다음에서 보듯이, 실행하려는 명령 앞에 nohup을 붙이면 된다.
$ nohup find/ -name core |
출력 위치를 재지정하지 않았다면 nohup은 표준 출력에 결과를 출력한다. 표준 오류는 현재 디렉터리에 있는 nohup.out이라는 파일에 출력한다.
출력 위치를 원하는 파일로 재지정해도 좋다. 하지만 이 때는 오류와 출력을 모두 재지정해야 한다.
$ nohup find/ -name core >/tmp/corefind.out 2>&1 |
나는 2-3분이 넘게 걸린다 싶은 명령은 거의 자동으로 nohup을 사용한다. 콘솔에서 명령을 실행하는 경우도 마찬가지다. 연결이 끊어졌을 때 프로세스가 죽지 않는 기능도 유용하지만, 사실은 출력을 자동으로 재지정하는 기능이 편리해서다.
이 기사에서 살펴본 기교를 사용하면 유닉스 시스템에서 원하는 프로세스와 관련 정보를 신속하게 찾아낼 수 있으리라 믿는다. 다양한 유닉스 계열을 관리하는 경우 명령행 옵션을 사용하여 결과 형식을 표준화하면 원하는 프로세스를 찾기가 더욱 쉬워진다.
교육
-
IBM Redbooks 사이트에서 썬 솔라리스 관리자를 위한 IBM AIX® 레드북을 찾아 읽어보기 바란다. 이 책은 솔라리스 시스템 관리자 입장에서 AIX 시스템이 썬 시스템과 다른 점을 설명한다.
-
System Administration Toolkit:: 이 연재에 속하는 다른 기사를 읽어본다.
-
Marty Poniatowski가 쓴 HP-UX 11i System Administration Handbook and Toolkit(Prentice Hall PTR, ISBN: 0-13-060081-3)은 HP-UX에 관한 정보를 제공하며 HP-UX와 다른 운영체제를 비교한다. HP-UX가 제공하는 명령을 살펴보고 명령 수행 결과를 다른 운영체제와 비교한다.
-
Bash: 표준 본 셸과 문법은 비슷하나 기능이 더 풍부한 셸이다. 별칭(alias), 작업 제어(job control), 파일/디렉터리 이름 자동 완성(auto-completion) 등 다양한 기능을 제공한다.
-
Zsh: Bash와 비슷한 기능을 제공하지만 일부 셸 컴포넌트(예: 명령 자동 완성 기능)를 확장할 수 있다.
-
AIX®와 유닉스 기사: Martin Brown이 쓴 다른 기사와 튜토리얼을 살펴본다.
- AIX/유닉스 라이브러리는 다음 주제에 관련한 정보를 제공한다.
-
AIX and UNIX: AIX 시스템 관리와 유닉스 기술을 확장하기 위한 풍부한 정보를 제공한다.
-
AIX and UNIX 입문: AIX와 UNIX 초보자에게 좋은 정보를 제공하는 사이트다.
-
AIX 5L™ 위키: AIX와 관련한 기술 정보를 공동으로 수집하고 관리하는 공간이다.
-
사파리 온라인 서점: 다양한 기술 서적과 기술 자료를 제공한다.
-
developerWorks 기술 행사와 웹 캐스트: 최신 기술 동향과 이벤트 정보를 놓치지 말기 바란다.
-
포드캐스트: IBM 기술 전문가들과 만날 수 있다.
제품 및 기술 얻기
-
IBM 평가판 소프트웨어: developerWorks에서 내려받은 소프트웨어로 다음번 프로젝트에 활용하자.
토론
-
developerWorks 블로그를 읽어보고 developerWorks 공동체에 참여하자.
-
AIX와 유닉스 포럼에 참여하자.
Martin Brown은 8년 넘게 기술 필자로 활약해왔다. Brown은 다양한 주제를 다루는 수 많은 책을 집필했고 기사를 작성했다. Brown은 펄, 파이썬, 자바(Java™), 자바스크립트, 베이직, 파스칼, 모듈라-2, C, C++, 레볼, gawk, 셸 스크립트, 윈도우(Windows®), 솔라리스, 리눅스, BeOS, 맥 OS X을 비롯하여 웹 프로그래밍, 시스템 관리, 통합에 이르리까지 다양한 개발 언어와 플랫폼을 경험했다. Brown은 마이크로소프트(Microsoft®) SME(Subject Matter Expert)이며 ServerWatch.com, LinuxToday.com, IBM developerWorks에 주기적으로 기고한다. Brown은 또한 컴퓨터월드, 애플 블로그, 기타 사이트에 주기적으로 블로그 기사를 올린다. 연락 주소는 Brown이 운영하는 웹 사이트를 참조하기 바란다.