Linux generic

psycho 2011. 9. 25. 14:58

 수많은 Unix Console 응용프로그램들이 출력을 stdin/stdout/stderr 등으로 redirect하는 옵션을 자체적으로 지원한다. 이는 원래 Unix의 응용프로그램 설계 철학에 의한 것으로, 하나의 프로그램은 단순한 하나의 기능을 제공하여 사용자의 명령 이해와 처리 방법 설계에 도움을 주고, 버그 발생 가능성을 줄이며, 수행 속도를 높인다는 것이 그것이다. 여러 개의 기능이 필요한 것은 redirection을 이용하여 데이터가 여러 프로그램을 거치도록 한다. 많은 경우에 일일이 파일로 출력하고, 다시 출력된 파일을 가지고 작업해야 하는 DOS/Windows1보다 훨씬 효율적이다.

 문제는, 그럼에도 불구하고 가끔씩 옵션 목록에 stdin/stdout 등이 없는 "불친절한" 소프트웨어가 존재한다는 것이다. 개발자에게 물어보거나 소스를 뜯어본다면 알아낼 수 있을지도 모르지만, 그 얼마나 귀찮은 일이란 말인가? 이런 녀석들을 위해서 중간 생성물을 저장해야 한다니, 끔찍한 일이다. 그렇다면 이런 공간낭비를 줄일 수 있는 방법을 알아보도록 하자.

 혹시 wget이라는 녀석을 모르는 분이 있는가? 모르는 분들은 그냥 "다운로더"쯤으로 생각하자. URL 주소를 이용하여 파일을 받을 수 있으며, 나름 상당한 수준의 기능을 제공한다. 설명을 위해 이 녀석을 예로 들겠다. 상황은 다음과 같다. 예를 든 상황이 좀 어색해 보이긴 하지만, 어찌됐든 그렇다고 가정하자.


 - 당신은 이제부터 FreeBSD를 써보기로 결심했다. DVD로 굽기 위해 설치 이미지를 받으려고 보니, ISO 이미지 파일을 xz라는 프로그램으로 압축한 녀석이었다. 써먹으려면 일단 이 녀석을 받은 다음, xz로 압축을 풀어야 한다. 그런데 문제는, 파일을 받을 공간은 있지만 파일을 받고 나면 공간이 부족해서 압축을 풀 수가 없다는 것이다. 어떻게 하면 좋을까?


 파일을 받으면서 데이터를 stdout으로 출력하고, pipe를 사용하여 xz에 넘기면 압축을 푼 상태로 저장할 수 있을 것이다. 그런데 wget의 도움말을 아무리 뒤적여봐도 도무지 받은 데이터를 stdout으로 출력하는 방법이 나와있지 않다. 이대로 포기해야만 할까?


 아는 사람이면 애초에 이런 글을 읽지도 않을 것이므로 설명하자면, Linux에서는 어떤 프로세스든 기본적으로 0번부터 2번까지 3개의 File Descriptor를 열게 되어 있다. 0은 stdin, 1은 stdout, 2는 stderr이다. 그리고 이 녀석들은 /proc/(PID)/fd를 통하여 접근할 수 있다. 그리고 PID에 상관없이 프로세스 자신의 정보에 접근할 수 있는 링크가 있는데, 그것은 /proc/self를 통해 가능하다. 이제는 슬슬 감이 오는가? 그렇다. wget의 출력파일 이름을 /proc/self/fd/1로 하면 받은 파일의 내용을 그대로 stdout으로 출력하게 된다. 그렇다면, 조금 전에 예로 든 상황이라면 다음과 같이 하면 될 것이다.


# wget -O /proc/self/fd/1 "URL://location.of/download.file/you.wish" | xz -cd > "Name.to.save.contents"


 이 방법은 파일로의 입력/출력을 지원하는 어떤 프로그램에도 적용할 수 있다. 이는 자체적으로 stdin 입력이나 stdout/stderr 출력을 지원하는 프로그램도 마찬가지이다. 예를 들어, dd의 경우 입력 파일을 지정하지 않으면 stdin을, 출력 파일을 지정하지 않으면 stdout을 기본으로 사용하지만, 입력에 /proc/self/fd/0을, 출력에 /proc/self/fd/1을 주어도 동일하게 동작한다. 적절히 응용하면 파일 입력만을 지원하는 프로그램에 stdin 입력을 줄 수도 있다.


※ 추가 : BSD에서도 같은 기능이 있는지에 대한 조사를 해본 결과, /dev/stdin, /dev/stdout, /dev/stderr도 같은 기능을 한다.

             실제로는 이쪽이 표준인 듯도 하다.

각주 1

운영체제 차원에서야 당연히 지원하지만, 써먹을 수 있는 응용프로그램이 많지 않다.

  1. 운영체제 차원에서야 당연히 지원하지만, 써먹을 수 있는 응용프로그램이 많지 않다. [본문으로]