사용자 인터페이스_10 파일 압축 시 실행 상태를 표시하는 진행바 표시하기

 
  • 출처 : 유닉스 리눅스 쉘스크립트 예제사전_한빛미디어

명령어: pv, tar, gzip
키워드: 압축, 진행바
사용처: 시간이 오래 걸리는 파일 처리 등에서 화면에 진행 상태를 나타내고 싶을 때


실행예제

$ ./tar-pv.sh
 693MB 0:00:42 [16.4MB/s] [              <=>                ]

스크립트

#!/bin/sh

DATA_DIR=/myapp/datadir

cd $DATA_DIR  #------------------------------------------------- 1
tar cf -bigfile1.dat bigfile2.dat |pv|gzip > archive.tar.gz  #-- 2

   

해설

이 스크립트는 tar 명령어와 gzip 명령어로 큰 파일을 아카이브할 때 처리 진행 상태를 pv 명령어로 표시합니다. tar 명령어로 현재 처리 중인 파일을 표시하려면 다음처럼 v 옵션을 사용합니다. 여기서 c 옵션은 아카이브 작성(Create), f 옵션은 아카이브를 파일로 작성(여기에서는 archive.tar) 한다는 의미입니다.

  • tar 명령어로 처리 중인 파일 표시

    $ tar cvf archive.tar *.dat
    datadir/1001.dat
    datadir/1002.dat
    datadir/1003.dat
    datadir/1004.dat
    ...
    

출력 결과를 보면 알 수 있듯이 tar 명령어의 v 옵션은 파일마다 표시되므로 큰 아카이브 파일 경우에는 현재 처리가 진행되고 있는지 아니면 멈췄는지 알기 어렵습니다. 이럴 때 쓰는게 pv 명령어입니다.

pv 명령어는 Pipe Viewer 약어로 파이프 처리 중 데이터 흐름을 가시화합니다. pv 명령어에서 쓰는 주요 옵션은 아래와 같습니다.

  • pv 명령어 주요 옵션

    옵션 의미
    -a 진행바가 아닌 파이프에 흐르는 데이터의 평균 속도를 표시합니다.
    -b 처리를 바이트 숫자만 표시하며 진행바는 표시하지 않습니다.
    -L 파이프 전송량을 제한합니다. 초당 전송량은 k(킬로), m(메가), g(기가) 단위의 바이트 수로 지정합니다.
    -q 조용한(quiet)모드입니다. -L로 전송량 제한만 하고 싶을 때 사용합니다.
    -s 파이프에 흐르는 데이터 크기를 미리 지정합니다. 이것으로 100% 진행바를 표시합니다.

예제는 우선 1에서 셸 변수 DATA_DIR로 지정한 디렉터리로 이동합니다. 이 디렉터리에는 무척 큰 데이터 파일인, bigfile1.data와  bigfile2.dat가 있습니다. 2에서 파일을 합쳐서 tar.gz 형식으로 아카이브합니다. tar 명령어 인수에 -(하이픈)이 있는데 이것은 명령어 출력을 파일이 아닌 표준 출력으로 보내겠다고 지정하는 것입니다.

따라서 tar 아카이브된 데이터 열은 파이프로 pv 명령어에 그대로 전달됩니다. pv 명령어는 처리 상태를 표준 에러 출력에 표시하면서 동시에 파이프 접속 대상인 gzip 명령어에 데이터 열을 넘깁니다. gzip 명령어는 표준 입력의 tar 아카이브를 받아서 gzip 압축을 해서 archive.tar.gz라는 파일에 출력합니다.

pv 명령어 기본 표시는 다음과 같습니다. 그 외에도 전송량 제한(-L) 같은 다양한 옵션이 있으므로 man pv로 확인 바랍니다.

  • pv 명령어 가시화 예제

    700MB 0:00:42 [16.4MB/s] [                 <=>                  ]
    
    700MB     : 파이프 처리한 데이터 크기
    0:00:42   : 처리 시간
    16.4MB/s  : 평균 속도
    [  <=>  ] : 진행바
    

이렇듯 pv 명령어는 표준 입력을 그대로 출력하면서 처리 결과를 표준 에러 출력에 순차적으로 알기 쉽게 표시하는 기능입니다. ‘데이터 흐름을 가시화하는 cat 명령어’라고 생각하면 이해하기 쉽습니다.

   

주의사항

  • pv 명령어를 써서 전송량을 제한하려면 -L 옵션을 이용합니다. dd 명령어를 사용해서 out.dat라는 1GB 파일을 만들 때 다른 프로세스에 영향을 주지 않도록 처리 속도를 제한하려면 다음과 같이 작성합니다.

    dd if=/dev/zero count=1024 bs=1024000 | pv -L 10m -s 1g > out.dat
    

    pv 명령어 옵션으로 -L 10m을 지정하면 dd 명령어 결과 1초간 최대 10MB까지 out.dat 파일에 출력됩니다. 또한 -s 1g 옵션으로 처리해야 할 총 크기가 1GB라는 걸 명시적으로 지정합니다. 이걸로 진행바가 100%까지 차오르게 표시됩니다.