래리 월의 ‘덕트 테이프’ 철학이 어떻게 Perl을 텍스트·웹 자동화의 실용적 도구로 만들었는지, 그리고 오늘날 텍스트 처리에서 여전히 유효한 실무 교훈은 무엇인지 설명합니다.

“덕트 테이프 프로그래밍”은 가장 좋은 도구가 종종 문제를 빠르게 해결해 주는 도구라는 생각입니다 — 예쁘지 않거나 영구적이지 않더라도, 또는 근사한 시스템으로 설계된 것이 아니더라도 말이죠.
그것은 대충 작업하라는 뜻이 아닙니다. 지저분한 입력, 불완전한 사양, 그리고 우아한 아키텍처 다이어그램이 통하지 않는 마감일 앞에서 모멘텀(일의 진척)을 중시하는 태도입니다.
덕트 테이프 사고방식은 단순한 질문에서 시작합니다: 고통을 없애기 위해 가장 작은 변경은 무엇인가? 그건 10,000개의 파일 이름을 바꾸는 짧은 스크립트일 수도 있고, 로그에서 오류 라인만 뽑아내는 빠른 필터, 혹은 혼란스러운 내보내기를 스프레드시트가 읽을 수 있게 바꾸는 일회성 변환일 수도 있습니다.
이 글은 래리 월과 Perl을 그 태도의 역사적 사례로 사용하지만, 요점은 향수에 머무르지 않습니다. 텍스트, 로그, CSV, HTML 조각, 또는 실질적으로 일관성 없는 문자열 더미로 된 ‘데이터’를 다룰 때 여전히 적용되는 실용적 교훈을 뽑아내는 데 있습니다.
당신이 전문 프로그래머가 아니더라도 정기적으로 다음을 다룬다면 이 글은 정확히 당신을 위한 것입니다:
끝까지 읽으면 다음 네 가지를 분명히 얻을 수 있습니다:
래리 월은 ‘영리한’ 언어를 발명하려 한 사람이 아니었습니다. 그는 현업 엔지니어이자 시스템 관리자였고, 로그 파일, 리포트, 설정 조각, 메일 헤더, 그리고 매뉴얼이 약속한 형식과 잘 맞지 않는 임시 데이터 덤프 같은 다루기 힘든 텍스트를 다루며 하루를 보냈습니다.
1980년대 중반, Unix에는 이미 훌륭한 도구들이 있었습니다 — sh, grep, sed, awk, 파이프와 필터들. 하지만 실제 업무는 단일 깔끔한 명령으로 잘 들어맞지 않았습니다. 파이프라인으로 시작했다가 작은 상태 기계(state machine)가 필요하다는 걸 깨닫거나, 더 나은 문자열 처리가 필요하거나, 재사용 가능한 스크립트가 필요하거나, 다음 주에 고칠 수 있을 정도로 읽기 쉬운 상태를 유지해야 했습니다.
래리의 동기는 실용적이었습니다: 도구를 연결하고 텍스트를 변형해 유용한 결과를 얻어내는 '글루 작업(glue work)'의 마찰을 줄이는 것.
Perl의 원래 목표는 Unix 도구를 대체하는 것이 아니었습니다 — 한 줄짜리 파이프라인이 미니 프로그램으로 발전할 때 그것들을 조정하기 쉽게 만드는 것이었습니다. 여러 유틸리티(각각 다른 인용 규칙과 엣지 케이스를 가진)를 오가느니, Perl은 한 곳에서 다음을 제공했습니다:
그게 바로 ‘덕트 테이프’ 사고방식입니다: 완벽함이 아니라 빠르고 오래 버티는 해결책.
Perl 문화는 몇 가지 가치를 수용했습니다: 순수함보다 실용성, 격식보다 표현력, 그리고 유명한 “문제를 푸는 방법은 여러 가지가 있다”는 태도. 이것들은 슬로건이 아니라, 최소한의 고통으로 앞에 놓인 문제를 해결해도 된다는 허용이었습니다.
Perl의 초기 인기는 회고적으로 신비롭게 들릴 수 있지만, 그렇지 않습니다. 그 언어는 단지 당시 팀들이 필요로 하는 것과 맞아떨어졌습니다: 지저분한 입력을 견딜 수 있고, 기존 시스템과 통합되며, 피곤한 사람이 다음 호출이 오기 전에 동작하는 스크립트를 배포할 수 있게 해주는 언어였습니다.
초기 웹사이트는 애플리케이션 프레임워크나 관리형 서비스로 구동되지 않았습니다. 많은 사이트가 웹 서버와 CGI 스크립트가 들어있는 디렉터리, 몇 개의 플랫 파일, 그리고 아직 모든 것의 ‘중심’처럼 느껴지지 않는 단순한 데이터베이스로 구성되어 있었습니다.
운영은 로그 중심이었습니다: 접근 로그, 오류 로그, 업로드 폴더, 폼 제출을 받는 이메일 인박스, 그리고 조용히 데이터베이스가 된 텍스트 파일들. 무언가 고장나면 보통 어제 로그를 grep해서 원인을 진단하고 스크립트를 조금 고쳤습니다.
자동화는 단순히: 사람이 매번 수동으로 하지 않아도 반복 실행되는 작업이었습니다.
그 작업은 웹 요청으로 트리거될 수 있고(누군가 폼을 제출하거나, “검색”을 클릭하거나, 리포트를 다운로드), 혹은 예약작업(cron)이 되어 매시간 로그를 회전하거나 페이지를 재생성하거나 요약을 보내는 식이었습니다.
작은 사이트라도 필요했던 작업:
수작업으로 하면 시간 낭비뿐 아니라 오류와 지연을 초래했습니다.
Perl은 기존 도구들 사이에 적절히 들어맞았습니다:
grep, sed, awk, sort)Perl은 요청을 읽고 시스템 명령을 실행하며 지저분한 텍스트를 변형하고 HTML을 출력하거나 파일을 업데이트하는 것을 하나의 스크립트에서 할 수 있었습니다. 이런 ‘글루 언어’ 역할이 초기 웹 자동화를 실용적으로 만든 이유입니다: 개별적으로 유용하지만 함께 연결하기 번거로운 조각들을 안전하고 반복 가능하게 이어주었습니다.
Perl은 고전적인 Unix 커맨드라인 도구들과 웹 스크립팅의 새 세계 사이에 편하게 자리 잡을 수 있었기 때문에 ‘덕트 테이프’라는 별명을 얻었습니다. 데이터가 로그 파일, 이메일, CSV 내보내기, HTML 조각 등으로 시작되면 Perl이 그것을 잡아당겨 재구성하고 다음 단계로 넘길 수 있었습니다 — 전체 환경을 새로 받아들이도록 강요하지 않고도 말이죠.
기본 제공으로 Perl은 텍스트 조작을 매우 직접적으로 느껴지게 했습니다:
split, join, 치환)이 조합 덕분에 일상적인 파싱과 편집에 긴 툴체인이 필요하지 않았습니다.
Unix는 작은, 집중된 프로그램들을 연결하도록 권장합니다. Perl은 그 조각 중 하나로 작동할 수 있었습니다: 표준 입력에서 읽고 텍스트를 변형한 뒤 결과를 다음 툴에 출력합니다.
일반적인 사고 모델은 이렇습니다:
읽기 → 변형 → 쓰기
예: 서버 로그를 읽고 날짜 형식을 정규화하고 잡음을 제거한 뒤 정리된 파일을 쓰고, 필요하면 sort, uniq, grep 같은 도구에 파이핑할 수 있었습니다. Perl은 Unix 도구를 대체한 것이 아니라 awk + sed + shell 조합이 어색해질 때 그것들을 이어주는 풀입니다.
그 같은 스크립트 우선 접근법은 초기 웹 개발에도 이어졌습니다. Perl 스크립트는 폼 입력을 받아 다른 텍스트 스트림처럼 처리하고 HTML을 출력할 수 있었기에 시스템 유틸리티와 웹 페이지 사이의 실용적인 다리가 되었습니다.
Perl이 여러 Unix 계열 시스템에서 실행되었기 때문에, 팀은 종종 최소한의 변경으로 같은 스크립트를 다른 머신으로 옮길 수 있었습니다 — 배포가 단순하고 수동적이던 시절에는 큰 가치였습니다.
정규표현식(보통 ‘regex’로 줄임)은 텍스트 패턴을 묘사하는 방법입니다 — 마치 규칙을 가진 ‘찾아 바꾸기’ 도구와 같습니다. [email protected]이라는 정확한 문자열을 찾는 대신, 정규식은 “이것이 이메일 주소처럼 보이나?”라고 말할 수 있게 해줍니다. 이 한 가지 전환(정확한 매치에서 패턴 매치로)이 초기 자동화의 많은 부분을 가능하게 했습니다.
정규식을 작은 언어로 생각해 보세요. 다음과 같은 질문에 답하는 도구입니다:
스프레드시트에 텍스트를 붙여넣고 자동으로 열로 나누어주길 바랐던 적이 있다면, 정규식을 원했던 것입니다.
초기 웹 스크립트는 사람 손으로 입력된 폼 필드, 서버가 생성한 로그, 서로 다른 시스템이 이어붙인 파일 같은 지저분한 입력에 의존했습니다. 정규식은 세 가지 높은 가치의 작업을 빠르게 실용적으로 수행하게 해주었습니다:
입력 검증(예: “이것이 URL처럼 보이는가?”, “이것이 날짜처럼 보이는가?”)
필드 추출(예: 로그 라인에서 상태 코드와 요청 경로 뽑기)
내용 재작성(예: 전화번호 정규화, 오래된 링크 교체, 저장 전 사용자 입력 정리)
Perl의 정규식 지원은 단순히 존재하는 수준이 아니라 자주 사용되도록 설계되었습니다. 그것은 ‘덕트 테이프’ 사고방식과 완벽히 맞았습니다: 일관성 없는 텍스트에 몇 가지 규칙을 적용해 배포할 만큼 신뢰할 수 있는 결과를 얻는 것.
정규식은 사람들이 매일 접하는 ‘거의 구조화된’ 텍스트에 빛을 발합니다:
12/26/25를 2025-12-26으로 변환하거나 다양한 날짜 스타일 인식정규식은 너무 강력해서 난해해질 수 있습니다. 짧고 영리한 패턴 하나가 검토하고 디버그하기 어렵고, 입력 형식이 바뀌면 쉽게 깨집니다.
유지보수 가능한 접근법은 패턴을 작게 유지하고, 언어가 지원하면 주석을 추가하며, 다음 달에 누군가 손댈 가능성이 있다면 하나의 ‘천재적’ 표현보다 두 단계의 명확한 과정을 선호하는 것입니다.
Perl 원라이너는 아주 작은 스크립트로 생각하면 됩니다: 터미널에서 직접 실행해 텍스트를 변형하는 단일 목적의 명령들입니다. 한 번만의 정리, 일회성 마이그레이션, 혹은 전체 프로그램을 쓸 필요가 없는 빠른 점검에 유용합니다.
원라이너는 보통 표준 입력에서 읽어 변형을 하고 그 결과를 출력합니다. 예를 들어, 빈 줄을 제거하는 명령:
perl -ne 'print if /\S/' input.txt > output.txt
또는 공백으로 구분된 텍스트에서 특정 “열”(필드)을 추출하는 예:
perl -lane 'print "$F[0]\t$F[2]"' data.txt
배치 이름 변경의 경우, Perl은 기본 rename 도구보다 좀 더 제어해서 파일 작업을 수행할 수 있습니다:
perl -e 'for (@ARGV){(my $n=$_)=~s/\s+/_/g; rename $_,$n}' *
(마지막 예는 공백을 밑줄로 바꿉니다.)
원라이너는 다음의 경우 적절합니다:
진짜 스크립트를 써야 할 때:
“빠른”이 곧 “추적 불가”가 되어서는 안 됩니다. 셸 히스토리 라인을 저장하거나 저장소의 노트 파일에 붙여넣고, 변경 전/후 예시를 포함하고 무엇이 왜 변경되었는지 기록하세요.
같은 원라이너를 두 번 실행했다면 그 신호는 작은 스크립트로 포장해 파일 이름, 주석, 예측 가능한 입출력 경로를 부여할 때입니다.
CPAN(Comprehensive Perl Archive Network)은 간단히 말해 Perl용 공유 라이브러리 선반입니다: 누구나 다운로드해 쓸 수 있는 공개 모듈들의 모음입니다.
모든 기능을 처음부터 다시 쓰는 대신, 소규모 팀은 잘 테스트된 모듈을 가져와 실제 문제(오늘 바로 작동하는 스크립트 배포)에 집중할 수 있었습니다.
일상적인 웹 작업의 많은 부분이 단일 개발자에게도 가능해졌습니다. CPAN이 제공한 빌딩 블록의 예:
이것은 작은 스크립트 하나가 이미 바쁜 시스템에 추가되는 경우에 특히 중요했습니다. CPAN은 이미 현장에서 사용된 코드를 빌려와 더 빠르고 안전하게 스크립트를 구성할 수 있게 해주었습니다.
트레이드오프는 분명합니다: 의존성은 일종의 커밋입니다.
모듈을 끌어오면 즉시 시간을 절여주지만, 버전 호환성, 보안 패치, 모듈이 유지되지 않게 될 경우의 대비를 생각해야 합니다. 오늘의 빠른 이득이 내일의 혼란스러운 업그레이드로 이어질 수 있습니다.
CPAN 모듈에 의존하기 전에, 명시적으로 관리되는 모듈을 선호하세요:
신중하게 사용하면 CPAN은 ‘덕트 테이프’ 사고방식의 최고의 표현 중 하나입니다: 작동하는 것을 재사용하고, 계속 전진하고, 필요하지 않은 인프라는 만들지 말라.
CGI(Common Gateway Interface)는 요청이 들어올 때 프로그램을 그냥 실행하는 시기였습니다. 요청이 서버에 도달하면 서버는 당신의 Perl 스크립트를 실행했고, 스크립트는 환경 변수와 STDIN에서 입력을 읽고 응답(보통 HTTP 헤더와 HTML 블롭)을 출력했습니다.
간단히 말해 스크립트는:
name=Sam&age=42)Content-Type: text/html)를 출력한 뒤 HTML을 출력한다이 모델은 빠르게 유용한 것을 배포하게 만들었습니다. 동시에 위험한 것을 빠르게 배포하기도 쉬웠습니다.
Perl CGI는 실용적 웹 자동화의 지름길이었습니다:
이것들은 종종 소규모 팀의 승리였습니다: 하나의 스크립트, 하나의 URL, 즉각적인 가치.
CGI 스크립트는 요청마다 실행되므로 작은 실수들이 곱해졌습니다:
속도는 기능이지만 경계와 함께할 때만 그렇습니다. 빠른 스크립트라도 명확한 검증, 신중한 인용, 예측 가능한 출력 규칙 같은 경계가 필요합니다 — 이 습관들은 작은 관리자 도구를 쓰든 현대 웹 엔드포인트를 작성하든 여전히 유효합니다.
Perl은 ‘영리한’ 해결책을 쉽게 만들어 난독하다는 평판을 얻었습니다. 구두점이 많은 촘촘한 문법, 문맥에 따라 동작이 달라지는 요소들, 그리고 “방법은 많다”는 문화는 짧고 인상적인 코드를 장려했습니다. 2시의 그 짧은 해결법은 훌륭하지만, 6개월 뒤 원작자조차 그 원라이너가 정확히 무슨 일을 했는지 기억 못할 수 있습니다.
유지보수 문제의 핵심은 Perl이 특히 읽기 어렵다는 것이 아니라, Perl이 의도를 숨기도록 압축하는 것을 허용한다는 점입니다. 흔한 원인으로는 주석 없는 촘촘한 정규식, 암묵적 변수($_)의 과다 사용, 사이드 이펙트나 중첩 삼항연산자, 마법 같은 기본값 등이 있습니다 — 이들은 라인을 줄여주지만 이해를 희생합니다.
몇 가지 습관이 가독성을 크게 높입니다:
Perl 커뮤니티는 몇 가지 간단한 안전장치를 정규화했습니다: use strict;와 use warnings; 활성화, 기본적인 테스트(간단한 무결성 검사라도), 가정사항을 인라인 주석이나 POD로 문서화. 이들은 코드를 ‘엔터프라이즈화’시키지 않고도 생존 가능하게 만듭니다.
더 넓은 교훈은 어떤 언어든 적용됩니다: 미래의 당신과 팀 동료를 위해 작성하세요. 가장 빠른 스크립트는 요구사항이 바뀔 때도 안전하게 변경할 수 있는 스크립트입니다.
텍스트 작업이 깨끗해진 건 아닙니다 — 그 위치만 옮겨간 것뿐입니다. 당신이 CGI 스크립트를 유지보수하지 않을지라도 여전히 CSV 내보내기, SaaS 웹훅, 로그 파일, ‘임시’ 통합 피드를 다루고 있을 것입니다. Perl을 유용하게 만든 그 실용적 기술들은 여전히 시간을 절약하고(그리고 조용한 데이터 손상을 막아)줍니다.
대부분 문제는 “어려운 파싱”이 아니라 일관성 없는 입력입니다:
1,234 vs 1.234, 03/04/05 같은 날짜 표기, 다른 언어의 월 이름모든 입력을 ‘신뢰하지 마세요’, 심지어 ‘우리 시스템에서 왔다’ 하더라도요. 일찍 정규화하세요: 인코딩(보통 UTF-8) 선택, 개행 표준화, 분명한 잡음 제거, 일관된 스키마로 변환.
그다음 가정을 명시적으로 검증하세요: “이 파일은 7컬럼이다”, “ID는 숫자형이다”, “타임스탬프는 ISO‑8601이다”. 문제가 생기면 크게 실패하고(예: 오류를 기록하며) 샘플 라인과 행 번호, 원본 파일을 함께 기록하세요.
가능하면 명확한 포맷과 진짜 파서를 선호하세요. JSON이 오면 JSON을 파싱하세요. CSV가 오면 인용을 이해하는 CSV 파서를 쓰세요. 추측은 고객 이름 안의 쉼표 같은 엣지케이스가 조용히 결과를 망가뜨릴 때까지 통합니다.
이 기술들은 다음과 같은 일상 업무에서 쏠쏠한 이득을 줍니다: 장애 시 애플리케이션 로그 필터링, 재무 내보내기 정리, CRM 임포트 변환, API 통합 브릿지, 그리고 ‘거의 맞는’ 결과가 치명적인 한 번짜리 데이터 마이그레이션.
Perl의 ‘덕트 테이프’ 평판은 대충해서가 아니라 유용했기 때문입니다. 그 유산은 팀이 내보내기를 조정하거나 로그를 정규화하거나 반구조적 텍스트를 스프레드시트나 데이터베이스가 소화할 수 있게 변형해야 할 때마다 드러납니다.
오늘날 스크립팅은 보통 Python, Ruby, 또는 JavaScript(Node.js)를 기본으로 합니다. 이들의 고수준 역할은 겹칩니다: 빠른 자동화, 시스템 통합, 도구들 사이의 글루 코드.
Perl의 고전적 강점은(지금도 그러합니다) 운영체제에 대한 직접적인 접근, 표현력이 높은 텍스트 조작, 그리고 ‘그냥 일을 끝내자’는 문화였습니다. Python은 가독성과 풍부한 표준 라이브러리를, Ruby는 개발자 편의성과 웹 중심 관행을, JavaScript는 어디서나 실행 가능한 범용성을 제공합니다.
오늘날의 많은 작업은 프레임워크, 안정된 API, 클라우드 서비스, 더 나은 도구로 형성됩니다. 이전에 맞춤 스크립트가 필요했던 작업들이 이제는 관리형 서비스, 호스팅된 큐, 기성 연결자로 대체됩니다.
배포 방식도 달라졌습니다: 컨테이너, CI 파이프라인, 의존성 고정이 이제는 선택이 아니라 기대치입니다.
현실의 텍스트는 여전히 지저분합니다. 로그는 놀라움을 담고 있고, 내보내기는 ‘창의적’ 포맷을 담고 있으며, 데이터는 신뢰할 수 있게 변형되어야 합니다.
Perl이 가르친 지속적인 교훈은: 자동화의 80%는 파싱, 정리, 검증, 그리고 예측 가능한 출력 생성이라는 사실입니다.
최선의 선택은 보통 팀이 유지할 수 있는 도구입니다: 언어에 대한 익숙함, 생태계의 강점, 현실적인 배포 제약(무엇이 설치되어 있고, 보안 규칙이 무엇인지, 운영팀이 무엇을 지원할 수 있는지).
Perl 유산의 요점은 ‘항상 Perl을 써라’가 아니라 ‘당신이 실제로 가진 난장판에 맞는 도구를 선택하라’는 것입니다.
AI 보조 워크플로에서도 ‘덕트 테이프’ 본능이 나타납니다. 예를 들어, 로그 뷰어, CSV 정규화기, 작은 관리자 UI 같은 내부 도구를 빠르게 만들어야 할 때 대화형으로 반복할 수 있게 돕는 플랫폼(예: Koder.ai)이 유용할 수 있습니다. 다만 같은 주의가 필요합니다: 빠르게 배포하되 결과물을 읽기 쉽고 테스트 가능하며 롤백하기 쉬운 상태로 남기세요 — 오늘의 ‘임시’ 수정이 내일의 핵심 경로가 될 수 있습니다.
작업 중인 문제를 빠르게 해결하는 가장 작은 효과적인 변경을 사용하는 실용주의적 접근입니다. 지저분한 입력, 불완전한 사양, 그리고 우아한 아키텍처 다이어그램에 신경 쓸 시간이 없는 마감일 앞에서 유용합니다.
이것은 대충해도 된다는 면죄부가 아닙니다. “덕트 테이프”라는 비유는 작동하는 결과를 얻은 다음에 필요한 최소한의 안전장치(테스트, 백업, 메모 등)를 더해 그 임시방편이 나중에 함정이 되지 않도록 하는 것을 의미합니다.
“한 번 더” 규칙을 사용하세요: 같은 수작업 정리가 두 번 일어난다면 자동화하세요.
적합한 대상 예시:
작업이 프로덕션 데이터에 영향을 준다면 실행 전에 안전장치(드라이런, 백업, 검증)를 추가하세요.
원라이너를 ‘작은 스크립트’로 취급하세요:
길어지거나 오류 처리가 필요하거나 재사용될 경우, 인수와 명확한 입출력 경로를 갖춘 실제 스크립트로 옮기세요.
텍스트가 ‘거의 구조화되어 있는’(로그, 이메일, ID, 일관적이지 않은 구분자 등) 경우에 유용하며, 검증·추출·재작성 작업에 적합합니다.
유지보수를 위해:
빠른 해결책이 ‘영구적’이 되는 시점은 그 해결책이 반복적으로 사용되거나 다른 사람이 의존하거나 워크플로에 깊숙이 박혔을 때입니다.
강화가 필요하다는 신호:
그럴 때는 검증, 로깅, 테스트, 가정사항을 정리한 README를 추가하세요.
CPAN은 시간을 절여주지만, 모든 의존성은 일종의 약속입니다.
실용적 선택 체크리스트:
배포 계획도 세우세요: 버전 고정(pin), 설치 단계 문서화, 보안 업데이트 추적 등.
CGI 시대의 가장 큰 교훈은 경계 없는 속도는 취약성을 만든다는 것입니다.
입력을 받는다면:
이 습관들은 현대의 스크립트, 서버리스 함수, 웹 엔드포인트에도 그대로 적용됩니다.
일반적인 문제들:
일찍 정규화하세요(인코딩, 개행), 가정은 명시적으로 검증하고, 문제가 발생하면 해당 행/라인 샘플을 함께 크게 실패(fail loudly)하게 하세요.
경험적 규칙: 실제 포맷이면 제대로 된 파서를 쓰세요.
정규식과 임시 분해는 패턴 추출과 가벼운 정리에는 좋지만, 이름 안의 쉼표 같은 엣지케이스가 조용히 결과를 망가뜨릴 수 있습니다.
팀이 실제로 실행·유지관리할 수 있는 도구를 선택하세요:
Perl을 ‘오늘도 써라’는 말이 아니라: 실제로 가진 난장판(데이터)에 맞는 도구를 고르라는 것이 Perl 유산의 핵심입니다.