우리 집에는 레이저 프린터가 한 대 있습니다. HP LaserJet Pro CP1525nw 컬러 프린터는 꽤 오래된 모델이지만, 수년간 흔들림 없이 컬러 인쇄를 해내는 든든한 일꾼 역할을 해왔습니다. 몇 년 전 라즈베리 파이를 프린트 서버로 활용해 이 프린터를 가정용 네트워크에 연결해 두었습니다.
이 LaserJet은 홈 오피스에 큰 보탬이 되었습니다. 작년에 회사를 설립한 이후로 고객 미팅, 워크숍, 교육 세션에 사용할 유인물과 각종 자료를 인쇄하는 일을 이 작은 레이저 프린터에 의지하고 있습니다.
유일하게 아쉬운 점은 이 프린터가 단면 인쇄만 지원한다는 것입니다. 양면으로 인쇄하려면 별도의 인쇄 작업을 직접 구성해야 하는데, 이 과정이 번거롭고 손이 많이 갑니다. 예를 들어 LibreOffice에서는 홀수 페이지를 먼저 인쇄하고, 용지를 다시 넣은 뒤 짝수 페이지를 역순으로 인쇄하도록 인쇄 작업을 일일이 지정해야 합니다.

양면 인쇄가 번거로운 이유
누군가 보내준 PDF를 인쇄할 때도 절차는 마찬가지입니다. 4페이지짜리 문서라면 먼저 1쪽과 3쪽을 인쇄하고, 용지를 다시 넣어 2쪽과 4쪽을 역순으로 출력해야 합니다. GNOME 인쇄 대화상자에서는 “페이지 설정(Page Setup)”에서 홀수 또는 짝수 페이지만 인쇄하도록 선택할 수 있습니다.


인쇄 방식과 관계없이 전체 과정은 동일합니다. 홀수 페이지를 인쇄한 뒤, 출력된 용지 묶음을 용지 트레이에 다시 넣고, 짝수 페이지를 역순으로 인쇄하는 것입니다. 4페이지 문서라면 짝수 페이지를 역순으로 찍어야 3쪽 뒷면에 4쪽이, 1쪽 뒷면에 2쪽이 인쇄됩니다. 짝수 페이지를 인쇄할 때 역순 옵션 선택을 깜빡해서 긴 인쇄 작업 전체를 망친 적이 몇 번 있었는데, 그 좌절감이란 이루 말할 수 없습니다.
마찬가지로 홀수 페이지로 끝나는 문서를 다루는 요령도 잊기 쉽습니다. 5페이지 문서라면 먼저 1, 3, 5쪽을 인쇄하지만, 출력된 용지를 다시 넣을 때는 5쪽은 빼고 1쪽과 3쪽만 넣어야 합니다. 그렇지 않으면 5쪽 뒷면에 4쪽이, 3쪽 뒷면에 2쪽이 인쇄되고 1쪽 뒷면은 빈 채로 남게 됩니다.
Bash 스크립트로 자동화하기
이런 과정을 더 쉽고 안정적으로 만들기 위해 저는 양면 인쇄를 자동화하는 간단한 Bash 스크립트를 작성했습니다. 기본적으로 홀수 페이지를 인쇄하고, 용지를 다시 넣으라고 알려주며(필요하다면 마지막 페이지를 제거하라고 안내), 이후 짝수 페이지를 인쇄하는 일련의 과정을 감싸는 래퍼(wrapper)입니다.
양면 인쇄가 필요할 때는 먼저 문서를 PDF로 변환합니다. 이 작업은 매우 간단합니다. LibreOffice에는 PDF로 바로 내보낼 수 있는 도구 모음 아이콘이 있으며, 파일 → PDF로 내보내기(File → Export As → Export as PDF) 메뉴를 통해서도 같은 작업을 할 수 있습니다. 다른 응용 프로그램에서도 대개 PDF로 저장(Save to PDF) 기능을 제공합니다. 확실하지 않다면 GNOME에서 프린터 대신 PDF 파일로 인쇄하는 방법도 있습니다.


작동 원리
PDF로 저장한 후에는 Bash 스크립트가 나머지를 처리합니다. 사실상 lpr 명령을 자동화하여 인쇄를 편리하게 만드는 것입니다. 스크립트는 홀수 페이지를 먼저 인쇄하고, 용지를 다시 넣으라는 메시지를 표시한 뒤 짝수 페이지를 인쇄합니다. 문서의 페이지 수가 홀수라면, 용지를 다시 넣을 때 마지막 페이지를 제거하라고 추가로 알려줍니다. 아주 단순한 구조입니다.
스크립트에서 유일하게 “프로그래밍”에 해당하는 부분은 페이지 수를 구하고 그것이 홀수인지 짝수인지 판별하는 것입니다. 두 가지 모두 어렵지 않게 처리할 수 있습니다.
페이지 수를 확인할 때는 pdfinfo 명령을 사용합니다. 이 명령은 PDF 문서에 대한 유용한 정보를 출력합니다. 샘플 출력은 다음과 같습니다.
$ pdfinfo All\ training\ -\ catalog.pdf
Creator: Writer
Producer: LibreOffice 6.3
CreationDate: Fri Oct 18 16:06:07 2019 CDT
Tagged: no
UserProperties: no
Suspects: no
Form: none
JavaScript: no
Pages: 11
Encrypted: no
Page size: 612 x 792 pts (letter)
Page rot: 0
File size: 65623 bytes
Optimized: no
PDF version: 1.5
출력 형식이 규칙적이라 파싱이 아주 쉽습니다. 페이지 수를 얻기 위해 AWK 한 줄 스크립트로 Pages: 줄을 찾아 두 번째 필드를 출력합니다.
pages=$( pdfinfo "$1" | awk '/^Pages:/ {print $2}' )
홀수·짝수 여부는 나머지 연산자(%, 모듈로)로 2로 나눈 나머지를 확인해 판별합니다. 어떤 수를 2로 나눈 나머지는 짝수일 때 항상 0, 홀수일 때 항상 1입니다. 이 간단한 검사를 통해 문서의 페이지 수가 홀수인지 확인하고, 홀수라면 나머지 페이지를 인쇄하기 전에 마지막 페이지를 제거해야 함을 알 수 있습니다.
if [ $(( $pages % 2 )) -ne 0 ] ; then
이 정도면 print-duplex.sh Bash 스크립트를 작성하는 일은 간단합니다. 올바른 옵션과 함께 lpr을 호출하면 됩니다. 즉, 출력을 내 프린터로 보내고(lpr -P "HP_LaserJet_CP1525nw"), 홀수 페이지(-o page-set=odd) 또는 짝수 페이지(-o page-set=even)만 인쇄하며, 역순으로 인쇄(-o outputorder=reverse)하도록 지정하는 것입니다.
print-duplex.sh 전체 코드
#!/bin/sh
# print-duplex.sh
# simple wrapper to print duplex
cat<<EOF
$1 ($pages pages)
-------------------------------------------------------------------------------
Printing odd pages first
Please wait for job to finish printing...
-------------------------------------------------------------------------------
EOF
lpr -P "HP_LaserJet_CP1525nw" -o page-set=odd "$1"
sleep $pages
cat<<EOF
===============================================================================
Put paper back into the printer in EXACT OUTPUT ORDER (face down in tray)
then press ENTER
===============================================================================
EOF
pages=$( pdfinfo "$1" | awk '/^Pages:/ {print $2}' )
if [ $(( $pages % 2 )) -ne 0 ] ; then
echo '!! Remove the last page - this document has an odd number of pages'
fi
echo -n '>'
read x
cat<<EOF
-------------------------------------------------------------------------------
Printing even pages
Please wait for job to finish printing...
-------------------------------------------------------------------------------
EOF
lpr -P "HP_LaserJet_CP1525nw" -o page-set=even -o outputorder=reverse "$1"
스크립트의 진행 순서를 정리하면 다음과 같습니다.
- 1단계: pdfinfo와 AWK로 전체 페이지 수를 계산한 뒤, 홀수 페이지를 인쇄합니다.
- 2단계: 인쇄가 끝날 때까지 페이지 수만큼 대기(sleep)한 후, 출력된 용지를 출력 순서 그대로 뒷면이 위로 향하게 트레이에 넣고 Enter 키를 누르라는 안내를 표시합니다.
- 3단계: 페이지 수가 홀수라면 마지막 페이지를 제거하라고 경고합니다.
- 4단계: Enter 입력을 받으면 짝수 페이지를 역순으로 인쇄해 양면 문서를 완성합니다.
참고로 원본 코드에서는 첫 화면에 페이지 수를 표시하는 시점에 $pages 변수가 아직 계산되지 않으므로, 스크립트 초반에 pages=$( pdfinfo "$1" | awk '/^Pages:/ {print $2}' )를 먼저 실행해 두면 첫 안내 화면에도 정확한 페이지 수가 표시됩니다. 이 작은 스크립트 하나만 있으면 단면 전용 프린터에서도 실수 없이 깔끔한 양면 문서를 만들 수 있습니다.