POSIX Shell: 표준 함수(Function)

스크립트의 규모가 커지면 중복되는 코드를 줄이기 위해 함수(Function)를 사용해야 합니다.

POSIX 표준을 따르면서 어디서나 잘 작동하는 함수 작성법을 알아봅니다.

기본 문법

가장 중요한 차이점은 function이라는 키워드를 쓰지 않는다는 것입니다.

# POSIX 표준 방식 (권장 ✅)
함수이름() {
    # 실행할 내용
}

# Bash 전용 방식 (POSIX에서는 지양 ❌)
# function 함수이름 { ... }
  • 함수 정의: 반드시 함수를 호출하기 전에 먼저 정의되어 있어야 합니다. (보통 스크립트 상단에 배치)
  • 호출: 함수 이름만 적으면 실행됩니다. (괄호 () 없이 이름만 사용)

인자 전달 (Arguments)

함수로 값을 보낼 때는 별도의 파라미터 이름을 정의하지 않고, 스크립트 실행 인자와 똑같이 위치 매개변수($1, $2, …)를 사용합니다.

greet() {
    printf "안녕하세요, %s님!\n" "$1"
}

greet "홍길동"  # $1에 "홍길동"이 전달됨
변수의미
$1, $2첫 번째, 두 번째 인자
$#함수에 전달된 인자의 총 개수
$@전달된 모든 인자 목록

지역 변수 (Local Variables) 주의사항

이 부분이 POSIX 표준의 가장 큰 제약사항입니다.

  • Bash:

local 키워드를 사용하여 함수 내부에서만 쓰는 변수를 만들 수 있습니다.

  • POSIX (sh):

표준에는 local 키워드가 없습니다.

함수 안에서 선언한 변수도 기본적으로 전역 변수(Global)가 되어 스크립트 전체에 영향을 줍니다.

해결책: 함수 내에서만 쓰는 변수는 _var_name처럼 앞에 언더바를 붙이거나, 이름이 겹치지 않게 주의해서 지어야 합니다.

반환값 (Return Value)

함수의 실행 결과를 처리하는 방법은 두 가지입니다.

구분종료 상태 코드 (Exit Status)표준 출력 (Standard Output)
데이터 타입0 ~ 255 사이의 정수문자열 (텍스트 데이터)
확인 방법$? 변수로 확인$(함수이름) (명령어 치환)으로 캡처
주 용도성공(0) 또는 실패(그 외) 판별처리된 결과값 전달 (이름, 날짜 등)
비유“내 일 잘 끝냈어!” (결과 보고서의 합격/불합격 도장)“내가 만든 결과물이야.” (결과 보고서의 내용물)

return: 종료 상태 코드 반환

숫자(0~255)만 반환할 수 있으며, 주로 성공(0)과 실패(그 외)를 알리는 용도입니다.

is_file_exist() {
    if [ -f "$1" ]; then
        return 0 # 성공
    else
        return 1 # 실패
    fi
}

printf/echo: 데이터 결과 반환

문자열이나 계산 결과 자체를 받아야 할 때는 출력문을 이용하고 명령어 치환($())으로 낚아챕니다.

get_date() {
    printf "%s" "$(date +%Y-%m-%d)"
}

TODAY=$(get_date)
printf "오늘 날짜: %s\n" "$TODAY"

간단한 예시

#!/bin/sh

get_user_status() {
    _USER_NAME="TestUser1"  # 실제 사용자 이름을 여기에 설정
    
    if [ "$_USER_NAME" = "TestUser" ]; then
        # 1. 표준 출력으로 문자열을 내보냄 (반환 문자열)
        printf "Active User"
        # 2. 종료 코드로 성공을 알림 (명령어 마지막 실행 결과가 0)
        return 0
    else
        printf "Unknown"
        return 1
    fi
}

# 실행 및 데이터 캡처
STATUS_TEXT=$(get_user_status)  # "Active User"가 변수에 저장됨 , 출력 문자열($()): 함수가 무슨 데이터를 만들었는지 알려줌 (실제 값)
STATUS_CODE=$?                  # 0이 변수에 저장됨

printf "문자열 결과: %s\n" "$STATUS_TEXT"
printf "상태 코드: %d\n" "$STATUS_CODE"

로깅 함수 만들기

실제 프로젝트에서 유용하게 쓸 수 있는 메시지 출력 함수 예시입니다.

#!/bin/sh

# 로깅 함수 정의
log_message() {
    _LEVEL="$1"
    _MSG="$2"
    _TIME=$(date '+%H:%M:%S')

    # 형식: [시간] [로그레벨] 메시지
    printf "[%s] [%s] %s\n" "$_TIME" "$_LEVEL" "$_MSG"
}

# 함수 호출
log_message "INFO" "애플리케이션을 시작합니다."
log_message "WARN" "설정 파일이 없습니다. 기본값을 사용합니다."


if [ "$?" -eq 0 ]; then                                  # 상태 코드($?): 마지막 함수가 어떻게 끝났는지 알려줌 (성공/실패)
    log_message "SUCCESS" "작업이 성공적으로 끝났습니다."
fi

핵심 요약 (Checklist)

  • function 키워드는 빼자: 그냥 name() { ... } 형식을 사용하세요.
  • local은 표준이 아니다: 변수 이름 충돌에 주의하세요.
  • 인자는 $1, $2: 함수 호출 시 옆에 나열하면 됩니다.
  • 복잡한 결과는 printf: 값을 돌려받고 싶을 땐 출력을 이용하세요.

주의사항

“출력되는 모든 것” : 함수 안에서 printfecho로 찍는 모든 내용은 밖에서 $( )로 감싸는 순간 하나의 반환 문자열로 합쳐집니다.

my_func() {
    printf "Hello "
    printf "World"
}

RESULT=$(my_func)
# RESULT에는 "Hello World"가 들어갑니다.

$? 사용 시 주의 : $?바로 직전 명령의 상태코드라서 즉시 변수에 저장하는 습관이 중요해요.

STATUS_CODE=$?   # 이 줄은 OK

# 하지만 이런 경우 주의!
some_func
echo "결과 출력"   # 이 줄이 실행되면 $?가 덮어씌워짐
echo $?            # some_func의 코드가 아님!

$()와 서브쉘 비용

RESULT=$(my_func)  # 서브쉘이 생성됨 → 성능 비용 있음

댓글 달기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다

위로 스크롤