프로세스

만일 여러분이 유닉스나 리눅스를 사용한다면 ps 프로그램이란 것을 자주 사용할 것입니다.
ps란 시스템상에 있는 프로세스들의 목록을 보는데 필요한 프로그램입니다. 다음은 freebsd에서 출력된 프로세스 목록의 일부분입니다.
~ % ps ax
  PID  TT  STAT      TIME COMMAND
    0  ??  DLs    0:13.39  (swapper)
    1  ??  ILs    0:01.01 /sbin/init --
    2  ??  DL     0:30.69  (pagedaemon)
    3  ??  DL     0:00.00  (vmdaemon)
    4  ??  DL     0:29.74  (bufdaemon)
    5  ??  DL   236:28.60  (syncer)
  149  ??  Ss     0:57.04 syslogd -s
  168  ??  Is     0:00.01 rpc.statd
  186  ??  Ss     0:01.41 inetd -wW
  188  ??  Is     1:06.78 cron
  195  ??  Is     0:04.45 /usr/sbin/sshd
  197  ??  Ss     0:32.19 /usr/sbin/usbd
프로세스란, 간단히 말해서, 독립적인 작업입니다. 예를 들어 윈도우즈에서는 여러개의 창이 떠 있는 것을 볼 수 있는데, 각 창은 별개의 프로세스에 의해 동작된다고 볼 수 있습니다. 물론 유닉스 계열도 마찬가지입니다. 안정성을 말하자면 유닉스의 프로세스가 윈도우즈의 작업들보다 훨씬 더 안정적입니다. 윈도우즈의 파란나라를 아시죠?(파란색의 화면에 하얀 글씨로 얼토당토 않은 듯한 메시지를 보여줍니다. 대개는 다시 부팅을 해야 하지요.) 위의 출력 내용은 그러한 프로세스들이 떠 있는 것을 보여 줍니다.

펄에서 프로세스 이야기를 하는 것은, perl이 프로세스를 관리할 수 있기 떄문입니다. 펄에서 프로세스를 이용하는 방법에는 몇가지가 있습니다. 먼저 system 함수를 사용하는 법, backtick(``)을 사용하는 법, open 함수를 이용하는 법, exec 함수를 사용하는 법, fork 함수를 사용하는 법 등이 있습니다. 이 중에서 open 함수를 이용하는 법을 먼저 살펴보고, 다른 것들은 시간이 나면 보충하도록 하겠습니다. (사실은 게시판에 질문이 올라 왔길래, 답을 하려다가, 모든 분이 볼 수 있도록 여기 적습니다.)

open 함수와 프로세스

윈도우즈의 도스창이나 유닉스의 shell 상에서

C:\> type AUTOEXEC.BAT | find "SYS"

또는

# grep 'GET /perl/perl-6.a.html' access_log | grep '201.30.40.50'
과 같은 명령을 사용해 보셨을 것입니다. 여기서 `|'는 보통 PIPE라고 합니다.
PIPE는 한 프로그램에서 출력된 내용을 다른 프로그램으로 전달하는 역할을 합니다. 앞의 프로그램이 STDOUT으로 출력하는 내용을 PIPE 뒤에 오는 프로그램의 STDIN으로 보내주는 것이죠.
이와 유사한 개념을 open 함수와 함께 사용할 수 있습니다. 다음 코드를 보시기 바랍니다.
# pipe.pl

open(FH, "grep 'GET /perl/perl-6.a.html' access_log |" ) || die "Reading failed: $!";
my( $line, @array );
while( $line = <FH> ) {
	if( $line =~ /\b201\.30\.40\.1[2-9]\d\b/ ) { # \b는 boundary(경계), \d는 숫자입니다.
		push @array, $line;
	}
}
close FH; # 반드시, 반드시, 반드시, 반드시, 반드시, 해야 합니다.

print "IP 주소 201.30.40.120~199까지 접속한 기록\n";
foreach ( @array ) {
	print; # 특수변수 $_ 를 출력함.
}
이 프로그램의 핵심은
open(FH, "grep 'GET /perl/perl-6.a.html' access_log |" )
부분에서 "grep 'GET /perl/perl-6.a.html' access_log |"끝에 있는 `|'입니다.
open함수는 파일 이름의 끝에 `|'가 붙으면 이 것을 파일이 아닌 프로그램으로 인식합니다. 그리고 그 프로그램을 실행시키고, 그 프로그램이 출력하는 내용은 다음의 $line = <FH>에 의해서 읽혀집니다. 모든 것을 읽고 나면 반드시 close를 실행해야만 합니다. 그렇지 않으면 그 프로그램이 종료되기를 오랫동안 기다리게 되는 경우가 발생할 수 있습니다.

위의 경우는 다른 프로그램의 출력을 받는 경우인데, 다음은 다른 프로그램에 출력을 하는 경우입니다.

# writepipe.pl

open(FH, "| perl" ) || die "Writing failed: $!";
print FH qq!print "Hello\\n";!;
close FH; # 꼭, 꼭, 꼭, 꼭, 꼭!
위 프로그램은 perl을 실행시키고 그 프로세스에 'print "Hello\n"'를 출력합니다. 호출된 perl은 그 내용을 받아 들이고, close FH가 된 후에 실행합니다. 그 출력은 Hello가 되겠지요. 이 때, Hello 뒤에 \n이 아닌 \\n(\가 두개)를 사용한 이유는 스스로 생각해 보시기 바랍니다. 
하여간, 이번 경우에는 `|'가 뒤가 아닌 앞에 붙어 있습니다. 파일의 앞에 `|'가 붙으면 perl은 파일이름을 파일이 아닌 프로그램으로 인식하고 그 프로그램을 실행합니다. 그러면, 여러분의 프로그램은 해당 파일핸들(FH)에 print를 할 수 있습니다.

위 두 가지 경우 모두, open 함수는 해당하는 새 프로세스의 process id를 반환합니다. 따라서,

# writepipe2.pl

my $pid = open(FH, "| perl" ) || die "Writing failed: $!";
print "PID: $pid\n";
print FH qq!print "Hello\\n";!;
close FH; # 꼭, 꼭, 꼭, 꼭, 꼭!
로 해 보시면, 호출되는 프로그램의 process id를 볼 수 있습니다.

system

나중에...

fork

나중에...

exec

나중에...

역 따옴표(backtick(``))

음,,, 이 것은 간단합니다.

# backtick.pl

my $hello = `perl -e "print 'Hello'"`;
print "Answer: $hello\n";
perl 소스에서 "나 ' 대신 `를 사용하면, perl은 그 안에 있는 내용을 실행시킨 후 그 출력물을 반환합니다. 위 프로그램을 보시고 실행해 보시기 바랍니다.
이전 | 목록
Comments