Skip to content
isdnetworks
Go back

정규식 파싱이 놓치는 설정 형식

(수정됨)

.env 에서 값을 뽑는 sed 스크립트를 만들었더니 어떤 값은 빈 문자열로 나왔다. 따옴표가 있는 항목만 뽑히고 없는 항목은 패턴이 안 맞아 그대로 빠지고 있었다.

Table of contents

Open Table of contents

원인 — 따옴표 유무가 가른 결과

정규식이 KEY="value" 형태를 전제하고 있어서 KEY=value 에서는 치환이 일어나지 않았다. cut -d= -f2- 로 잘라 가져온 뒤에 따옴표만 벗기는 방식으로 바꿔 두 형태를 모두 받게 했다.

있으면 벗기고 없으면 그대로 두는 것이므로 형식에 의존하지 않는다. 형식을 전제한 패턴은 그 전제를 벗어난 입력에서 오류가 아니라 빈 값을 낸다.

주의 — 빈 값이 기본값으로 동작하는 위험

더 위험한 것은 못 뽑았을 때 조용히 빈 문자열이 되는 쪽이었다. 그 값이 DB_HOST 로 쓰이면 빈 값이 곧 localhost 를 뜻하게 되어 의도한 대상과 다른 곳에 붙는다.

실제로 운영 데이터베이스에 붙으려다 로컬에 붙은 적이 있었다. 그래서 항목이 없으면 빈 값이 아니라 exit 1 로 끝내고 메시지를 stderr 로 내게 했다.

조치 — 셸에 맡기는 방법의 대가

두 가지 방법이 있었는데 source .env 로 셸이 파일을 직접 읽게 하는 것과 줄 단위로 직접 파싱하는 것이다. 앞쪽은 따옴표든 아니든 전부 처리되므로 파싱을 안 해도 된다. 다만 파일 안에 $(...) 명령 치환이 들어 있으면 그것도 같이 실행된다.

내가 만든 파일이면 괜찮지만 밖에서 오는 파일에는 쓸 수 없는 방법이다. 뒤쪽을 골랐다. 이유는 이 스크립트가 받을 파일의 출처를 통제할 수 없어서다. 대신 따옴표와 주석과 중복 키를 직접 다뤄야 하는 것을 감수했다.

검증 — 주석과 중복 키

주석 처리된 옛 값이 위에 남아 있으면 그것이 먼저 잡히는 문제가 있었다. ^KEY= 로 줄 앞에서 시작하는 것만 잡게 하니 # 으로 시작하는 줄은 걸리지 않았다.

같은 키가 여러 번 있는 경우는 더 미묘한데 첫 번째를 쓸지 마지막을 쓸지가 읽는 쪽마다 다르다. 읽는 쪽과 다른 쪽을 고르면 스크립트가 뽑은 값과 프로그램이 쓰는 값이 갈리므로 중복이 있으면 알리게 했다.

배경 — 값에 섞인 구분자

DB_PASSWORD 처럼 = 가 값 안에 들어가는 항목이 있었다. -f2- 로 첫 구분자에서만 자르고 나머지는 값으로 두게 해서 뒤가 잘리지 않게 했다.

주석 기호가 값에 있는 경우도 있어서 값에는 따옴표를 붙이는 규칙을 정했다. 시작할 때 필요한 항목이 전부 뽑혔는지 한 번 확인하게 하되 값 자체는 찍지 않고 앞 몇 글자만 남겼다.

정리


Share this post on:

Previous Post
돌아가는 서비스의 컬럼을 암호화하며 정한 순서
Next Post
규격 대조가 배제한 원인 후보