개발 slecs

쉘 alias로 파일 복사가 조용히 실패하는 문제 해결

목차

cat 리다이렉트와 cp -i 인터랙티브 모드 때문에 파일이 조용히 덮어써지지 않던 상황을 결국 손으로 해결했다.


배경: 파일이 안 바뀌는데 에러도 없는 상황

제일 골치 아픈 버그가 뭔지 아나. 에러가 없는데 결과도 없는 거다. styles.css를 수정해서 반영하려고 했는데, 빌드도 되고 명령어도 조용히 끝나는데 실제 public/styles.css는 전혀 바뀌지 않은 상황이었다.

원인을 파고들어 보니 두 가지가 맞물려 있었다.

첫 번째는 cat 리다이렉트 문제. 쉘 환경이나 alias 설정에 따라 cat file > target 형태가 기대한 대로 동작하지 않는 경우가 있다. 특히 target 파일이 이미 존재할 때 일부 환경에서는 리다이렉트가 묵묵히 실패하거나, 빈 파일로 덮어쓰거나, 아예 스킵되기도 한다.

두 번째는 cp -i 문제. -i(interactive) 옵션은 덮어쓰기 전에 사용자 확인을 요구한다. 로컬 개발 환경에서 alias로 cp='cp -i'가 걸려 있으면, 스크립트나 자동화 흐름 안에서 cp를 호출할 때 프롬프트가 뜨거나, 비인터랙티브 컨텍스트에서는 그냥 조용히 실패한다. 에러 메시지도 없이.

이게 팀 환경에서 더 문제가 되는 이유는, 내 로컬에서는 됐는데 다른 팀원 환경에서는 안 된다 류의 상황이 생기기 때문이다. alias나 쉘 설정이 사람마다 다르니까.


실제로 뭐가 문제였나

명령어 패턴 문제점
cat source.css > public/styles.css 쉘/alias 환경에 따라 리다이렉트 동작 불일치
cp -i source.css public/styles.css 비인터랙티브 컨텍스트에서 조용한 실패
alias cp='cp -i' 설정 자동화 스크립트에서 예상 외 동작 유발

핵심은 두 방법 모두 "덮어쓰기 실패"를 에러로 알려주지 않는다는 점이다. 그러니 아무것도 모른 채 잘못된 파일로 계속 작업하게 된다.

# 문제가 됐던 패턴들
cat updated.css > public/styles.css   # 환경 따라 다름
cp -i updated.css public/styles.css   # 인터랙티브 프롬프트 또는 조용한 실패

# 우회: 명시적으로 강제 덮어쓰기
cp -f updated.css public/styles.css
# 또는 alias 무시하고 직접 호출
\cp updated.css public/styles.css

\cp는 bash에서 alias를 우회해서 원본 바이너리를 직접 호출하는 방법이다. 이런 식으로 alias 영향을 받지 않도록 명시하는 게 스크립트 안에서는 더 안전하다.


회고: 작은 파일 변경, 큰 삽질

styles.css 파일 하나 덮어쓰는 작업인데 생각보다 시간이 꽤 걸렸다. 사실 이런 류의 문제는 경험이 쌓이면 "아, 쉘 alias 문제겠다" 하고 바로 짚이는데, 처음 겪으면 왜 안 되는지 감도 잘 안 온다.

팀에서 이런 상황을 최소화하려면 몇 가지를 습관으로 만들어 두는 게 좋다.

  • 자동화 스크립트 안에서는 alias 의존하지 않기. \cp, /bin/cp 같이 경로나 이스케이프를 명시하거나, -f 옵션을 붙여서 의도를 분명히 드러낼 것.
  • 파일 복사 후 반드시 결과 검증. diffmd5sum이든 뭐든, "복사됐겠지" 하고 넘어가지 말기. 특히 빌드 산출물이나 static asset은 더더욱.
  • 쉘 환경 문서화. 팀원마다 .bashrc.zshrc 설정이 다르면 재현 안 되는 버그가 생긴다. 공통 alias 정책이나 주의사항은 온보딩 문서에 명시해두는 게 낫다.

public/styles.css처럼 빌드 결과물이 아닌 수동 관리 파일이 섞여 있는 구조 자체도 나중에 손봐야 할 부분이긴 하다. 수동 복사가 필요한 흐름이 있다는 건 자동화 빈틈이 있다는 신호이기도 하니까.

끝.


🛒 이 글과 어울리는 추천 상품

*위 링크는 쿠팡파트너스 활동의 일환이며, 일정액의 수수료를 제공받을 수 있습니다.

댓글 0

첫 댓글 달아줘.