노트

bash strict mode (set -euo pipefail)

Unofficial Bash Strict Mode

인프라#linux · 연결된 개념 3개

쉽게 말하면

bash strict mode는 공장 라인에서 불량이 하나라도 나오면 바로 라인을 세우는 규칙 같아요. 명령이 실패하거나 없는 변수를 쓰면 스크립트가 그 자리에서 멈춰서, 실패를 모른 채 다음 단계로 가는 사고를 막아요.

비유가 깨지는 곳 라인 정지 버튼만큼 확실하진 않아요. -e는 if 조건, &&·|| 왼쪽, 명령 치환 안에선 동작하지 않아요. 또 grep처럼 못 찾음을 1로 알리는 명령은 정상인데도 멈추니 || true로 의도를 드러내요.

셸 스크립트 맨 위에 두는 set -euo pipefail은 실패를 조용히 넘기지 않게 하는 관용구다. 공식 기능 이름은 아니고, 흔히 "비공식 bash strict mode"라고 부른다.

#!/usr/bin/env bash
set -euo pipefail
  • -e: 명령이 0이 아닌 종료 코드(exit status)를 내면 스크립트를 멈춘다. 명령마다 || exit 1을 붙일 필요가 없다
  • -u: 정의되지 않은 변수를 쓰면 오류로 멈춘다. rm -rf "$DIR/"에서 DIR 오타가 루트 삭제로 이어지는 사고를 막는다
  • -o pipefail: 파이프라인 중간 명령이 실패해도 마지막 명령의 성공만 보고 넘어가던 동작을 막는다. 실패한 명령 중 가장 오른쪽 것의 종료 코드가 파이프라인 결과가 된다

한계

  • -e는 if 조건, &&·|| 왼쪽, 명령 치환(command substitution) 안 등에서는 동작하지 않는다. 만능 안전장치로 믿지 말 것
  • grep처럼 "못 찾음"을 1로 알리는 명령은 정상 흐름에서도 스크립트를 멈춘다. grep ... || true처럼 의도를 드러낸다
  • 선택적 변수는 ${VAR:-기본값}으로 읽는다

오류를 숨기지 말고 드러내라는 예외 처리 원칙과 같은 생각이고, 반대 방향의 실수가 예외 삼키기다. CI 스크립트(GitLab CI/CD 파이프라인)에는 거의 필수다.

출처: Bash 매뉴얼: The Set Builtin · BashFAQ/105: set -e가 기대대로 동작하지 않는 이유

연결된 개념

이 노트를 가리키는 문서

아직 없습니다.

뜻이 가까운 노트

  • 환경변수 스코프와 source

    셸에서 만든 변수는 기본적으로 그 셸 안에서만 보이고, export해야 그 셸이 띄우는 자식 프로세스(child process)에 전달된다. 그리고 스크립트를 실행하면 자식 프로세스에서 돌기 때문에, 스크립트가 바꾼 환경은 부모 셸로 돌아오지 않는다.

  • 포트를 쓰는 프로세스 찾아 종료하기

    "address already in use"로 서버가 안 뜰 때, 그 포트를 잡고 있는 프로세스를 lsof로 찾아 끈다. lsof(list open files)는 열린 파일과 소켓을 쓰는 프로세스를 보여준다.

  • EAFP와 LBYL

    LBYL(Look Before You Leap, 뛰기 전에 살펴라)은 작업 전에 조건을 먼저 검사하는 스타일이고, EAFP(Easier to Ask Forgiveness than Permission, 허락보다 용서가 쉽다)는 일단 시도하고 실패하면 예외로 처리하는 스타일이다. 파이썬 공식 용어집은 EAFP를 파이썬의 흔한 스타일로 소개한다.

  • kubectl 디버깅 치트시트

    kubectl은 쿠버네티스 클러스터를 조회·조작하는 CLI(Command-Line Interface)다. 앱 개발자가 가장 자주 쓰는 건 "내 Pod가 떠 있나, 왜 죽었나"를 확인하는 명령들이다.

  • 보호 구문

    정상 흐름이 아닌 경우를 함수 앞부분에서 검사하고 바로 빠져나오는 조건문. 중첩된 if-else를 평평하게 펴서 핵심 흐름을 드러낸다.

보기 옵션