함수 정의와 호출
스크립트를 작성하다 보면 같은 패턴이 반복됩니다. 시작 메시지 출력, 구분선 그리기, 오류 로그 남기기. 처음에는 그냥 복사해서 씁니다. 그런데 나중에 형식을 바꾸고 싶으면? 복사한 곳을 전부 찾아서 수정해야 합니다.
함수는 이 문제를 해결합니다. 코드 덩어리에 이름을 붙이고, 그 이름만 불러서 실행합니다.
두 가지 정의 문법
Bash에서 함수를 정의하는 방법은 두 가지입니다.
# 문법 1: function 키워드 사용function greet { echo "안녕하세요!"}# 문법 2: 괄호 문법 (POSIX 호환)greet() { echo "안녕하세요!"}
두 방법 모두 동작이 같습니다. function 키워드를 쓰면 Bash 함수임을 명시적으로 나타낼 수 있고, 괄호 문법은 sh, dash 같은 다른 쉘과도 호환됩니다. 어느 쪽을 쓰든 상관없지만, 한 프로젝트 안에서는 일관되게 사용하는 것이 좋습니다.
중괄호 { } 안의 첫 번째 명령어는 여는 중괄호와 같은 줄에 쓰거나, 반드시 세미콜론으로 구분해야 합니다. 그리고 닫는 중괄호 앞에는 세미콜론 또는 줄바꿈이 필요합니다.
# 올바른 예greet() { echo "안녕"; }greet() { echo "안녕"}# 잘못된 예 (오류 발생)greet() {echo "안녕"}
함수 호출
함수를 호출할 때는 이름만 씁니다. 괄호를 붙이지 않습니다. Bash에서 greet()처럼 괄호를 붙이면 함수 정의로 해석됩니다.
# 함수 호출greet# 인수와 함께 호출greet "철수"
정의 위치의 중요성
Bash는 스크립트를 위에서 아래로 읽으면서 실행합니다. 함수를 사용하기 전에 반드시 정의되어 있어야 합니다. 정의보다 호출이 먼저 나오면 오류가 발생합니다.
# 잘못된 순서 — 오류 발생greet # 아직 greet가 정의되지 않았음greet() { echo "안녕하세요!"}
관례적으로 스크립트 위쪽에 함수를 모두 정의하고, 아래쪽에서 실행 코드를 씁니다. 또는 main 함수를 만들고 스크립트 맨 마지막에 main을 호출하는 패턴을 씁니다. 이렇게 하면 정의 순서 걱정 없이 코드를 구성할 수 있습니다.
main() { greet print_separator}greet() { echo "안녕하세요!"}print_separator() { echo "================================"}main # 맨 마지막에 진입점 호출
main을 마지막에 호출하면 그 시점에는 greet와 print_separator가 이미 정의된 상태입니다. 실행 순서와 정의 순서를 분리할 수 있어서 코드 구성이 자유로워집니다.
실습: 구분선 출력 함수와 로그 출력 함수
구분선을 긋고 로그를 출력하는 함수를 만들어봅니다. 스크립트에서 가장 자주 쓰는 패턴입니다.
#!/bin/bash# 새 파일: separator_log.sh# 구분선 출력 함수print_separator() { echo "=================================================="}# 로그 출력 함수 (타임스탬프 포함)log() { local timestamp timestamp=$(date "+%Y-%m-%d %H:%M:%S") echo "[$timestamp] $1"}# 섹션 제목 출력 함수print_section() { print_separator echo " $1" print_separator}# --- 실행 ---print_section "시스템 정보 수집"log "스크립트 시작"log "현재 사용자: $(whoami)"log "현재 디렉토리: $(pwd)"log "스크립트 완료"print_separator
실행 결과는 다음과 같습니다.
==================================================
시스템 정보 수집
==================================================
[2026-04-24 20:00:00] 스크립트 시작
[2026-04-24 20:00:00] 현재 사용자: ubuntu
[2026-04-24 20:00:00] 현재 디렉토리: /home/ubuntu
[2026-04-24 20:00:00] 스크립트 완료
==================================================
log 함수 안에서 local timestamp를 사용했습니다. 이 부분은 다음 절에서 자세히 다루지만, 함수 안에서 만드는 변수는 local로 선언하는 것이 좋습니다. 함수 밖에서 선언한 변수에 영향을 주지 않기 위해서입니다.
print_section 함수는 print_separator를 두 번 호출합니다. 함수가 다른 함수를 호출하는 것도 자연스럽게 동작합니다. 코드 재사용이 중첩되어 더 간결해집니다.