← 모두의 툴

cURL 명령어 생성기가 조용히 깨지는 순간 — 셸 이스케이핑의 비대칭

가이드 · 2026.08.25 최종 확인

API를 테스트할 때 cURL 생성기에 헤더 값을 입력하고 명령어를 복사해 터미널에 붙여넣었는데 알 수 없는 문법 오류가 난 적이 있다면, 원인은 도구의 버그가 아니라 셸(bash 등)의 인용 규칙 자체에 있을 가능성이 높습니다. 이 가이드는 왜 작은따옴표(')가 셸에서 특별 취급되는지, 그리고 그 결과 cURL 명령어를 자동 생성하는 도구들이 필드마다 다르게 동작할 수밖에 없는 구조적 이유를 코드 레벨에서 분해합니다.

1. 작은따옴표 안에서는 왜 백슬래시도 무의미한가

bash 같은 POSIX 계열 셸에서 작은따옴표로 감싼 문자열은 "완전 리터럴"로 처리됩니다. 큰따옴표(")로 감쌌을 때는 \", \\, \$ 같은 일부 문자에 한해 백슬래시 이스케이프가 여전히 동작하지만, 작은따옴표 안에서는 그런 예외가 전혀 없습니다. 백슬래시조차 그냥 문자 그대로 취급됩니다. 그 결과 작은따옴표로 감싼 문자열 안에 작은따옴표 자체를 넣을 방법이 셸 문법 안에는 존재하지 않습니다 — 인용을 시작한 그 따옴표와 똑같은 문자를 안에서 "이스케이프해서 무시시킬" 수단이 아예 없는 것입니다.

2. 그래서 등장하는 `'...'\''...'` 트릭

이 제약을 우회하는 유일한 방법은 인용 구간을 잘게 쪼개는 것입니다. It's broken이라는 문자열을 셸에 안전하게 전달하려면 'It'\''s broken'처럼 씁니다. 이는 세 조각의 연결입니다: ① 'It' — 작은따옴표로 감싼 리터럴 "It", ② \' — 따옴표 밖에서 백슬래시로 이스케이프된 작은따옴표 문자 하나, ③ 's broken' — 다시 작은따옴표로 감싼 리터럴 "s broken". 셸은 인접한 토큰들을 공백 없이 이어 붙이므로 최종적으로는 "It's broken" 한 단어가 됩니다. 사용자 입력을 셸 명령어에 프로그램적으로 끼워 넣는 도구라면 이 변환을 자동으로 해줘야 안전합니다.

3. cURL 생성기의 실제 코드: 본문은 안전, 나머지는 무방비

modoohub의 cURL 생성기 코드를 직접 확인한 결과, 이 변환이 일관되게 적용되지 않고 있습니다. 요청 본문(-d)을 조립하는 부분은 body.replace(/'/g,"'\\''")로 정확히 위 3단계 트릭을 자동 적용합니다. 반면 헤더 값, Bearer 토큰, URL을 조립하는 부분은 -H '헤더이름: 헤더값' 형태로 값을 작은따옴표로 감싸기만 할 뿐 내부의 작은따옴표를 전혀 이스케이프하지 않습니다. 즉 같은 명령어 안에서도 필드에 따라 안전 수준이 다른 비대칭 구조입니다. 이는 이 도구만의 특이 사례가 아니라, 본문만 이스케이프를 신경 쓰고 헤더는 "값이 짧으니 괜찮겠지"라고 넘어가는 흔한 구현 패턴입니다.

4. 실전 예시: 헤더 값에 아포스트로피가 있을 때

커스텀 헤더 값으로 It's broken을 입력했다고 가정하면, 생성기는 다음과 같은 명령어를 만듭니다.

단계내용
입력한 헤더 값X-Note: It's broken
생성된 명령어 조각-H 'X-Note: It's broken'
셸의 실제 해석'X-Note: It'(리터럴) + s(공백 없이 이어붙는 단어) → 인자값이 "X-Note: Its"로 변형, 이어서 broken'에서 닫히지 않은 작은따옴표를 만나 문법 오류 또는 입력 대기 상태로 멈춤

대화형 터미널에서는 프롬프트가 >로 바뀌며 다음 작은따옴표가 나올 때까지 무한정 입력을 기다리고, 스크립트로 실행하면 unexpected EOF while looking for matching \`'' 같은 오류로 끝납니다. 값이 짧고 흔한 아포스트로피 한 글자 때문에 명령어 전체가 원래 의도와 전혀 다르게 동작하는 셈입니다.

5. 언제 안전하고 언제 직접 손봐야 하는가

자주 묻는 질문

Q. cURL 생성기의 본문(-d) 필드는 왜 안전한가요?

코드에서 본문 값을 body.replace(/'/g,"'\\''")로 처리해 값 안의 모든 작은따옴표를 셸이 안전하게 읽을 수 있는 3단계 형태로 자동 변환하기 때문입니다. 헤더·URL·Bearer 토큰 필드에는 이 처리가 적용되지 않습니다.

Q. 큰따옴표(")로 감싸면 이 문제가 해결되지 않나요?

아포스트로피 문제는 해결되지만 대신 큰따옴표 안에서 특별 취급되는 $(변수 확장), \`(명령어 치환), \\(이스케이프)가 새로운 문제를 일으킬 수 있습니다. 값에 이런 문자가 섞여 있으면 의도치 않게 셸 명령어나 변수로 해석될 위험이 있어 근본적인 해결책은 아닙니다.

Q. Windows PowerShell에서도 같은 문제가 생기나요?

PowerShell의 인용 규칙은 bash와 다릅니다(작은따옴표 안에서 작은따옴표 두 개를 연속으로 써서 이스케이프하는 방식). 이 가이드는 macOS/Linux의 기본 셸인 bash·zsh 기준이며, PowerShell에서 생성된 명령어를 그대로 붙여넣으면 또 다른 방식으로 깨질 수 있습니다.

Q. 이 문제를 피하는 가장 간단한 방법은?

헤더 값이나 URL에 작은따옴표가 들어갈 가능성이 있다면, 생성기 결과를 그대로 실행하지 말고 값 부분만 '\'' 패턴으로 직접 고친 뒤 실행하세요. 또는 정규식 생성기로 아포스트로피 포함 여부를 미리 검사하는 것도 방법입니다.