· KLDP.org · KLDP.net · KLDP Wiki · KLDP BBS ·
Devel Filter Skeleton

Developing Filter Programs


UNIX의 대부분 유틸리티들은 filter(필터) 형식으로 되어 있습니다. 즉, 표준 입력(stdin)으로 데이터를 받아서 가공한 다음, 이 가공된 데이터를 표준 출력(stdout)으로 출력합니다. 또한 처리 도중 발생한 에러는 표준 에러 출력(stderr)으로 출력합니다. 또한 대부분의 유틸리티들은 처리 방식에 영향을 주는 여러 가지 옵션을 받아서 처리할 수 있으며, 표준 입력 대신, command-line argument(명령 인자)로, 하나 또는 여러 개의 파일 이름을 입력 받아 작업하기도 합니다. 이런 유틸리티에는 대표적인 UNIX 유틸리티인, cat(1), wc(1), cut(1), paste(1) 등등 여러 가지가 준비되어 있습니다.

여러분이 특별한 필터 프로그램을 만들어야 할 경우, 이러한 UNIX 유틸리티들의 방식을 그대로 따와서 동작 방식을 비슷하게 만들어 두면, 나중에 shell script를 만들 때에도 편리하며, 배포시에도 상당히 효과를 볼 수 있습니다.

1.1. Options

1.1.1. Conventional Options


UNIX의 대부분 필터 프로그램들은 처리할 데이터가 담긴 파일들을 (command-line argument로) 받기 전에, '-'로 시작하는 옵션들을 받습니다. 옵션들은 보통 한 글자로 되어 있으며, 여러 개의 옵션을 하나로 받기도 합니다. 예를 들어 어떤 필터 프로그램이 '-v'와 '-r'이라는 옵션을 받아 처리할 수 있다고 해 봅시다. 이 프로그램 이름은 편의상 foo라고 하겠습니다. 이 경우, foo를 실행하는 방법은 다음 네 가지로 볼 수 있습니다:

$ foo -v -r data.file
$ foo -r -v data.file
$ foo -vr data.file
$ foo -rv data.file

옵션에 따라 추가로 argument를 받아서 처리하는 옵션도 있습니다. 이 경우 옵션 바로 뒤에 이 옵션을 위한 인자가 붙습니다. 예를 들어 foo 명령은 원래 처리 결과를 표준 출력으로 출력하지만 '-o filename'을 쓸 경우, 주어진 파일, filename에 그 결과를 저장한다고 합시다. 이 경우, '-v'와 '-r'을 함께 쓰기 위해, 다음 중 하나를 선택하면 됩니다.

$ foo -v -r -o out.file data.file
$ foo -v -o out.file -r data.file
$ foo -rv -o out.file data.file
$ foo -o out.file -vr data.file
$ foo -rvo out.file data.file

물론 위에서 나열한 방법 이외에도 여러 가지 조합이 가능합니다.

대부분의 필터 프로그램을 실행할 때, 처리할 파일 이름을 주지 않으면, 대개 표준 입력에서 데이터를 받습니다. cat(1)처럼 입력 데이터를 바로 출력하는 필터의 경우 다음과 같이 동작합니다.

$ cat data.file
hello, world
greetings, folks.
$ cat
hello, world
^d      # press control-D to acknowledge EOF.
hello, world
$ _

즉, 위 결과을 보면, cat(1)의 입력으로 data.file이란 파일을 주면 바로 그 파일의 내용을 출력합니다. 또 아무런 파일 이름없이 바로 실행하면, cat(1)은 사용자가 표준 입력에서 입력을 받기 위해 대기합니다. 이 때 "hello, world\n"를 입력하고 control-d 키를 누르면 EOF(end-of-file)을 전달해서, 입력이 끝났다는 것을 알려줍니다. 그러면 cat(1)이 그 입력을 받아서 출력하게 됩니다.

때에 따라서 여러 개의 파일과 표준 입력에서 들어오는 입력을 동시에 처리해야 하는 경우도 있습니다. 예를 들어서 출력하고자 하는 내용이 1.txt, 2.txt, 3.txt라는 파일에 들어 있는 내용이고, 또한 표준 입력에서 받은 내용도 출력하기를 원한다고 가정해 봅시다. 출력하는 순서는 1.txt 그리고 표준 입력에서 받은 내용, 그리고 2.txt와 3.txt 순서로 출력하려 합니다. 그러면 어떻게 cat(1)을 실행해야 할까요? 분명 1.txt, 2.txt, 3.txt를 순서대로 출력하기 위해서는 다음과 같이 해야 합니다:

$ cat 1.txt 2.txt 3.txt

그러나 우리가 원하는 것은 1.txt와 2.txt 사이에 표준 입력에서 데이터가 들어오는 것이기 때문에 위와 같이 할 수 없습니다. 게다가 cat(1)을 비롯한 대부분의 필터 프로그램은, 파일 이름을 하나 이상 주었을 경우, 표준 입력에서 데이터를 받지 않습니다.

해결책은 의외로 간단합니다. 파일 이름이 올 자리에 "-"를 주게 되면, cat(1)을 비롯, 대부분의 필터 프로그램이 표준 입력에서 입력을 받습니다. 따라서 다음과 같이 실행하면 문제가 해결됩니다:

$ cat 1.txt - 2.txt 3.txt

'-' 문자가 (위와 같이) 단독으로 쓰일 경우, 대부분의 필터 프로그램은 다음과 같이 인식합니다.

첫째. 입력 데이터 파일 이름이 올 자리에 '-'를 쓴 경우, 표준 입력에서 데이터를 받게 됩니다.

둘째, 출력 데이터 파일 이름이 올 자리에 '-'를 쓴 경우, 표준 출력으로 데이터를 출력합니다.

한가지 더, 모든 필터 프로그램이 '-'를 이러한 목적으로 사용하는 것은 아닙니다. 특정 프로그램이 '-'를 특별한 파일 이름으로 취급하는지 먼저 테스트해 보고 사용하기 바랍니다.

특정 옵션 글자가 어떤 뜻을 가지고 있는지 외워 두기란 쉬운 일이 아니지만, 아래 표를 보면 대부분 명령들이 각 옵션을 어떠한 뜻으로 쓰는 지 알 수 있습니다:

-o filename 출력 파일 이름을 지정합니다. 보통 이 옵션을 쓰면 프로그램의 출력이 표준 출력이나 기타 다른 곳으로 가지 않고 지정한 filename으로 가게 됩니다.
-v 또는 -V 상황에 따라서 프로그램의 version을 출력하고 종료하거나, 프로그램이 작업 도중 자세한 메시지를 출력하게 하는, verbose mode를 쓰도록 합니다.
-h 또는 -? 이 프로그램을 쓰는 방법을 알려주고 끝냅니다.
-f 보통 작업 결과가 기존 파일을 덮어쓰게 되는 경우, 필터 프로그램은 덮어 쓰지 않고 경고 메시지를 출력하고 끝내지만, 이 -f (force를 뜻함)를 쓰면, 무시하고 기존 파일을 덮어 쓰게 됩니다.
-t arg 또는 -T arg 특정 타입, 예를 들어 입력 데이터 형식이나, 출력 페이지 종류 등의 어떤 타입을 입력받는데에 쓰입니다.
-q 대개 quiet mode, 즉, 작업 도중 어떤 메시지도 출력하지 않게 합니다.
-r 또는 -R 대개 recursive mode, 즉, 입력 인자 중 디렉토리가 있을 경우, 그 디렉토리 아래의 모든 파일들도 포함해서 작업합니다.
-b 또는 -r bare 또는 binary 또는 raw, 입력 파일에 특별한 처리를 하지 않고 그대로 쓸 것을 지시합니다.
-i 입력 파일을 지정하는 데에 쓰거나 (input), 여러 가지 일을 수행할 때 일일히 사용자에게 물어보게 합니다 (interactive).

물론, 프로그램에 따라 위에 쓰인 옵션 이외의 다른 옵션을 쓰는 경우도 있고, 위의 해석과는 전혀 다른 뜻을 가진 것으로 해석하기도 합니다. 이는 순전히, 필터 프로그램을 만드는 개발자 마음대로지만, 여러분이 새 필터 프로그램을 만든다면, 위의 표를 참고해서 개발하면, 다른 사용자들이 쉽게 적응할 수 있습니다.

1.1.2. Long Options


대부분 옵션이 한 글자로 이루어져 있기 때문에, 자주 쓰는 필터 프로그램이 아닌 이상, 각 옵션이 어떤 기능을 하는지 외워두기란 쉬운 일이 아닙니다. 따라서 GNU에서 제공하는 대부분의 필터 프로그램은 '-'로 시작하는 한 글자 옵션 이외에도 '--'로 시작하고 여러 글자로 이루어진 옵션들도 제공합니다. 보통 '--'로 시작하는 옵션들을 long option이라고 합니다.

예를 들어, 도움말을 출력하기 위해 보통 '-h'나 '-?'를 쓰지만, 'help'를 쓸 수도 있습니다. 또, 한 글자 옵션으로 verbose mode를 지정하기 위해 '-v'를 써야 하는지 '-V'를 써야 하는지 헷갈리기 쉽지만, 'verbose'를 쓸 수 있다면 궂이 신경써서 외워둘 필요가 없습니다.

--help 도움말을 출력하고 끝냅니다.
--version 프로그램 버전을 출력하고 끝냅니다.
--quiet 조용하게 처리합니다. 즉, 따로 메시지를 출력하지 않습니다.
--verbose 처리 도중 메시지를 자세하게 출력합니다.
--recursive 인자로 디렉토리가 들어 올 경우, 그 디렉토리 하위 모든 파일도 같이 포함합니다.
--interactive 사용자에게 일일히 물어보고 작업하게 합니다.
--input 입력 파일을 지정합니다.
--output 출력 파일을 지정합니다.

또한 한 글자 옵션과 긴 옵션이 다른 점 중 하나는, 옵션이 인자를 받을 때입니다. 한 글자 옵션인 경우, '-o filename'과 같이 옵션 글자 뒤에 공백을 두고 파일 이름을 받지만, 긴 옵션인 경우, 옵션 뒤에 '='를 붙이고 공백 없이 입력합니다. 즉, '--output=filename'과 같이 씁니다.

1.2. Messages

프로그램이 작업을 처리하는 도중, 경고나 뜻하지 않은 상황을 만나게 되거나, 기타 사용자에게 알릴 내용이 있을 경우, 메시지를 출력하게 됩니다. 보통 작업 결과와 겹치지 않게 하기 위해, 이러한 메시지들은 표준 출력으로 나가지 않고, 표준 에러 출력으로 나가게 됩니다.

또한 입력 파일을 처리하는 도중, 원치 않는 입력을 만나게 될 경우, 에러 메시지를 출력하게 되는데, 이 경우, 에러 메시지가 다음과 같은 형식을 띄게 해야 합니다. 아래에서 (*)로 표시한 것이 자주 쓰는 형식입니다:

  • file-name: line-number: error-message (*)
  • file-name: line-number: column-number: error-message

  • program-name: error-message (*)
  • program-name: file-name: error-message
  • program-name: file-name: line-number: error-message

1.3. Exit Status


프로그램이 정상 종료했을 경우, exit status를 0으로 하고, 에러가 발생한 경우, 1-255 사이의 숫자를 쓰도록 합니다. 보통, 성공했을 경우 0을, 실패했을 경우 1을 쓰는 것으로 충분합니다.

1.4. Helper Files


프로그램을 시작할 때, 보통 수 많은 옵션이 필요하거나, 많은 양의 설정이 필요할 경우, 옵션 형태로 제공하는 것은 사용자에게 많은 불편을 줍니다. 이 경우, 미리 설정 파일을 만들어 두고, 사용자가 필요한 설정을 고치게 한 다음, 프로그램이 시작할 때, 이 설정 파일을 읽어서 동작하게 하면 좋습니다. (만약 설정 파일을 읽을 때 에러가 발생할 경우 앞에서 설명한 방식으로 에러를 출력하게 하면 더욱 좋습니다.)

설정 파일은 보통 전체 사용자들에게 영향을 주는 설정 파일과, 현재 사용자에게만 영향을 주는 설정 파일로 나눌 수 있습니다. 전자를 system-wide init file이라고 하고, 후자를 user init file이라고 부르겠습니다.

system-wide init file의 경우, 보통 /etc 아래에 위치합니다. 만약 프로그램의 이름이 foo라고 할 경우, system-wide init file은 보통 다음과 같이 만듭니다. (*) 표시가 있는 것이 자주 쓰입니다.

  • /etc/foorc (*)
  • /etc/foo/foorc 또는 /etc/foo/*
  • /etc/foo.d/foorc 또는 /etc/foo.d/*

user init file의 경우, 사용자 홈 디렉토리 (환경 변수 $HOME에 저장되어 있음)에 다음과 같은 파일 이름을 씁니다. (*) 표시가 있는 것이 자주 쓰입니다.

  • $HOME/.foorc (*)
  • $HOME/.foo/foorc 또는 $HOME/.foo/*

자주 쓰이지는 않지만 만약, 써야 할 설정 파일이 여러 벌 있어야 하는 경우, 이 외에 두 가지를 더 생각할 수 있습니다. 첫째, 프로그램에서 옵션을 써서, init file을 입력받을 수 있게 제공하는 것입니다. 둘째, 환경 변수를 써서 init file의 위치를 지정하게 하고, 프로그램에서 이 환경 변수가 가리키는 파일을 init file로 쓰는 것입니다. 후자의 경우, 프로그램 이름 뒤에 DIR를 붙인 이름을 환경 변수 이름으로 씁니다. 예를 들어 프로그램 이름이 foo인 경우, FOODIR 환경 변수를 씁니다.

2. 언어별 Filter Skeleton 만들기


2.1. DevelFilterCSkeleton

C 언어로 필터 프로그램을 만들기 위한 방법을 소개합니다.

2.2. DevelFilterBashSkeleton

Bash shell script로 필터 프로그램을 만들기 위한 방법을 소개합니다.

2.3. DevelFilterPythonSkeleton

Python으로 필터 프로그램을 만들기 위한 방법을 소개합니다.


끝 - ([http]신성국)




sponsored by andamiro
sponsored by cdnetworks
sponsored by HP

Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2005-07-11 09:47:17
Processing time 0.0459 sec