기술 · 실용 가이드
sed의 “unterminated s command”, 이스케이프를 더하기 전에 경계를 증명하세요
이 진단은 sed에 도착한 치환 프로그램에 유효한 종료 경계가 없다는 뜻일 뿐입니다. 실제 인수와 바이트를 수집하고 네 가지 실패군으로 분류한 뒤 제자리 편집 없이 수정 결과를 검증합니다.

“unterminated s command”는 파서 보고이지 완전한 원인 진단이 아닙니다. sed가 받은 치환 프로그램에서 기대한 위치의 종료 구분자가 사라졌습니다. 원본 구문에 구분자가 없거나, 데이터가 같은 구분자를 포함하거나, 확장 값에 CR 또는 줄바꿈이 있거나, 앞선 파서가 따옴표나 백슬래시를 먼저 소비했을 수 있습니다.
프로세스 경계에서 시작합니다. 이스케이프를 바꾸기 전에 sed에 전달된 정확한 인수와 바이트를 확보합니다. 깨진 경계가 보이면 그것을 소유한 계층만 수정하고, 작은 픽스처에서 -i 없이 출력을 비교한 뒤 차이가 정확할 때만 제자리 편집을 추가합니다.
1. sed가 실제로 받은 값을 수집합니다
최소 입력으로 재현하고 먼저 -i를 제거합니다. 셸 추적은 단서일 뿐입니다. 지원하는 셸에서는 인수를 한 줄씩 안전하게 출력하고 od나 xxd로 일반 터미널에 숨은 구분자, 백슬래시, CR, 줄바꿈을 확인합니다.
대화형 셸 또는 스크립트, 매개변수 확장, 명령 치환, YAML 또는 CI 템플릿, SSH 또는 컨테이너 래퍼, 마지막으로 sed 순서로 소유자를 기록합니다. eval은 새로운 파서를 추가해 증거를 바꾸므로 쓰지 않습니다.
2. 깨진 경계를 분류합니다
최종 sed 인수에 세 번째 구분자가 없다면 문법을 고칩니다. 패턴이나 대체 데이터에 구분자가 있으면 안전한 구분자를 선택하거나 해당 필드만 이스케이프합니다. CR이나 줄바꿈이 있으면 다중 행 데이터가 이 명령에 속하는지 먼저 결정합니다.
로컬에서는 맞지만 CI, YAML, SSH, 명령 치환에서 깨지면 각 전달 지점의 바이트를 비교합니다. 처음 달라지는 경계가 수정 소유자이며 뒤에서 백슬래시를 더하면 원인만 가립니다.
3. 패턴과 대체문을 따로 처리합니다
정규식 필드와 대체 필드는 다른 언어입니다. 정규식 메타문자는 패턴 결정입니다. 대체문에서는 이스케이프하지 않은 &가 일치 텍스트를 삽입하고 백슬래시가 대체 이스케이프를 시작합니다. 셸 인용을 먼저 만족한 뒤 해당 필드에 필요한 최소 처리만 합니다.
데이터가 복잡하면 필드 전용 인코더를 쓰거나 제어된 템플릿에서 sed 스크립트 파일을 생성합니다. 구조화 파서나 언어 라이브러리가 경계를 명시할 수 있다면 신뢰하지 않는 문자열을 셸이나 sed 문법에 이어 붙이지 않습니다.
4. 정상 값 하나가 아니라 실패 행렬을 시험합니다
작은 픽스처에서 빈 값, 공백, 선택한 구분자, &, 백슬래시, CR, 줄바꿈, 불일치 값을 시험합니다. stdout을 정확한 예상 파일과 비교해 오류만 사라진 잘못된 변환을 통과시키지 않습니다.
이전에 실패한 실제 래퍼를 통해 다시 시험합니다. 터미널 직접 성공은 YAML, SSH, 컨테이너 진입점, 빌드 변수를 검증하지 않습니다. 수집한 인수와 예상 출력을 회귀 테스트로 보존합니다.
5. 차이가 정확한 뒤에만 제자리 편집을 추가합니다
검증한 식을 먼저 복사본에 실행합니다. GNU, BSD, BusyBox sed의 -i와 백업 접미사 형식이 다르므로 구현을 확인하고 중요한 파일에는 백업 또는 원자적 교체 경로를 둡니다.
실제 래퍼가 검토된 바이트를 내보내고 픽스처 차이가 정확하며 경계 데이터가 리터럴로 유지되고 복사본이 한 번만 바뀌어야 완료입니다. 소유자나 바이트가 불명확하면 stdout 단계에서 멈추고 증거를 보존합니다.
