///

Bash Script Essentials Capsule

스크립트 어디서 호출돼도 자기 위치 찾기, 경로가 디렉토리인지 심볼릭 링크인지 구분하기 — 이 두 패턴이 거의 모든 Bash 스크립트의 도입부에 필요하다.

///

kind: capsule status: active visibility: private license: CC-BY-SA-4.0 summary: Bash 스크립트 두 가지 필수 패턴 — 자기 디렉토리 얻기 (BASH_SOURCE) + 디렉토리/심볼릭 링크 존재 체크 (-d / -L). tags: - bash - shell - scripting - capsule


Bash Script Essentials Capsule

Summary#

스크립트 어디서 호출돼도 자기 위치 찾기, 경로가 디렉토리인지 심볼릭 링크인지 구분하기 — 이 두 패턴이 거의 모든 Bash 스크립트의 도입부에 필요하다.

Claim#

1. 스크립트 자기 디렉토리 얻기#

#!/usr/bin/env bash
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
  • BASH_SOURCE[0] = 현재 실행 중인 스크립트 경로 ($0 와 달리 source 시에도 스크립트 이름)
  • cd …; pwd 로 절대경로 canonicalize
  • 심볼릭 링크가 스크립트 자체를 가리킬 땐 멀티라인 resolver 필요 (아래)

심볼릭 링크까지 resolve (완전판)#

get_script_dir() {
  local SOURCE_PATH="${BASH_SOURCE[0]}"
  while [ -L "$SOURCE_PATH" ]; do
    local SYMLINK_DIR=$(cd -P "$(dirname "$SOURCE_PATH")" >/dev/null 2>&1 && pwd)
    SOURCE_PATH=$(readlink "$SOURCE_PATH")
    <span class="missing-link">$SOURCE_PATH != /*</span> && SOURCE_PATH="$SYMLINK_DIR/$SOURCE_PATH"
  done
  cd -P "$(dirname "$SOURCE_PATH")" >/dev/null 2>&1 && pwd
}

source, bash -c, alias, symlink 모두 대응.

2. 디렉토리 존재 여부#

if [ -d "$DIRECTORY" ]; then
  echo "exists"
fi

if [ ! -d "$DIRECTORY" ]; then
  echo "does not exist"
fi
  • -d디렉토리와 "디렉토리를 가리키는 심볼릭 링크" 둘 다 true
  • 심볼릭 링크를 따로 다루려면 -L 추가 체크

디렉토리 vs 심볼릭 링크 분기#

if [ -d "$X" ]; then
  if [ -L "$X" ]; then
    rm "$X"        # 심볼릭 링크는 rm
  else
    rmdir "$X"     # 실제 디렉토리는 rmdir
  fi
fi

Scope#

  • Bash 4.0+ (BASH_SOURCE 는 bash 특화 — /bin/sh$0 만).
  • macOS 기본 bash 3.2 에서도 위 구문 동작.

Caveats#

  • 변수는 항상 큰따옴표로 감싸기 — 경로에 공백/특수문자 있으면 참사.
  • pwd -P vs pwd 차이 (심볼릭 링크 resolve 여부) 스크립트 목적에 맞춰 선택.
  • readlink -f 는 GNU coreutils 전용 — macOS 는 Homebrew coreutils 설치 후 greadlink -f.

Source#

Supplementary: - Grundlefleck — Check if directory exists (CC BY-SA 4.0)

Sagwan Revalidation 2026-04-18T21:12:16Z#

  • verdict: ok
  • note: BASH_SOURCE, -d/-L 패턴 모두 현재 Bash 4+/5+ 관행과 일치하며 오탈자·모순 없음.