소개

이 실습에서는 리눅스 셸 함수에 대해 알아봅니다. 셸 함수는 특정 작업을 수행하는 재사용 가능한 코드 블록으로, 스크립트를 더욱 체계적이고 효율적으로 만들어 줍니다. 셸 스크립트에서 함수를 만들고 호출하며, 매개변수를 사용하는 방법을 배우게 됩니다. 이 실습은 초보자를 위해 설계되었으므로, 각 개념을 단계별로 상세히 설명하겠습니다.

이 과정은 학습과 연습을 돕기 위해 단계별 지침을 제공하는 가이드 실습입니다. 각 단계를 주의 깊게 따라가며 직접 실습해 보세요. 통계에 따르면 이 실습은 초급 수준이며, 97%의 수료율과 학습자들로부터 100%의 긍정적인 평가를 받았습니다.

첫 번째 셸 함수 만들기

가장 먼저 간단한 셸 함수를 만들어 보겠습니다. 셸 함수는 큰 스크립트 안에 포함된 작은 스크립트와 같아서, 특정 작업을 수행하는 명령들을 하나로 묶을 수 있게 해줍니다.

먼저 새 파일을 만들어야 합니다. 터미널을 열고 다음을 입력하세요:

cd ~/project
touch functions.sh

이 명령은 project 디렉터리로 이동한 뒤 functions.sh라는 새 파일을 생성합니다. 이 파일에 우리가 만들 셸 함수들을 작성할 것입니다.

이제 첫 번째 함수를 추가해 봅시다:

#!/bin/bash

## 이것은 간단한 함수입니다
greet() {
  echo "Hello, World!"
}

## 이 줄은 함수를 호출(실행)합니다
greet

코드를 하나씩 살펴봅시다:

  • 첫 번째 줄인 #!/bin/bash는 쉬뱅 (shebang) 이라고 불립니다. 시스템에 이 스크립트를 해석할 때 bash 를 사용하라고 알려주는 역할을 합니다.
  • greet() { } 구문으로 함수를 정의합니다. 중괄호 { } 사이에 있는 모든 내용이 함수의 본문이 됩니다.
  • 함수 내부에는 "Hello, World!"를 출력하는 간단한 echo 명령이 있습니다.
  • 마지막 줄의 greet는 우리가 정의한 함수를 호출하여 실행합니다.

이제 스크립트에 실행 권한을 부여하고 실행해 보겠습니다:

chmod +x functions.sh
./functions.sh

다음과 같은 결과가 출력되어야 합니다:

Hello, World!

만약 이 결과가 보이지 않는다면, functions.sh 파일에 오타가 없는지 다시 한번 확인해 보세요.

매개변수가 있는 함수

기본적인 함수를 만들어 보았으니, 이번에는 매개변수를 추가하여 함수를 더 유연하게 만들어 보겠습니다. 매개변수를 사용하면 함수 내부로 정보를 전달할 수 있습니다.

functions.sh 파일을 다시 열고 내용을 다음 코드로 교체하세요:

#!/bin/bash

## 매개변수가 있는 함수
greet() {
  echo "Hello, $1!"
}

## 여러 개의 매개변수가 있는 함수
calculate() {
  echo "The sum of $1 and $2 is $(($1 + $2))"
}

## 인자와 함께 함수 호출
greet "Alice"
calculate 5 3

이 코드를 분석해 봅시다:

  • greet 함수에서 $1은 함수에 전달된 첫 번째 인자를 가리킵니다.
  • calculate 함수에서 $1$2는 각각 첫 번째와 두 번째 인자를 의미합니다.
  • $(($1 + $2)) 구문은 두 매개변수의 산술 덧셈을 수행합니다.

스크립트를 실행합니다:

./functions.sh

다음과 같은 결과가 출력되어야 합니다:

Hello, Alice!
The sum of 5 and 3 is 8

출력 결과가 다르다면 파일의 변경 사항이 올바르게 저장되었는지 확인하세요.

함수의 반환 값

셸 스크립팅에서 함수는 다른 프로그래밍 언어와 같은 방식으로 값을 반환하지 않습니다. 대신 결과를 출력 (echo) 하여 캡처하거나, 전역 변수를 수정하는 방식을 사용합니다. 두 가지 방법을 모두 알아보겠습니다.

functions.sh를 다시 열고 내용을 다음과 같이 업데이트하세요:

#!/bin/bash

## 결과를 출력하는 함수
get_square() {
  echo $(($1 * $1))
}

## 전역 변수를 수정하는 함수
RESULT=0
set_global_result() {
  RESULT=$(($1 * $1))
}

## 출력된 결과를 캡처
square_of_5=$(get_square 5)
echo "The square of 5 is $square_of_5"

## 함수를 사용하여 전역 변수 수정
set_global_result 6
echo "The square of 6 is $RESULT"

상세 설명:

  • get_square 함수는 echo를 사용하여 결과를 출력하며, 우리는 $() 구문을 사용하여 이 출력을 변수에 담습니다.
  • set_global_result 함수는 전역 변수인 RESULT의 값을 직접 수정합니다.
  • $()를 사용하여 get_square의 실행 결과를 변수에 할당하는 방식을 확인하세요.
  • set_global_result를 호출하면 RESULT 값이 변경되며, 그 후 RESULT를 출력하여 확인합니다.

파일을 저장하고 실행합니다:

./functions.sh

다음과 같은 결과가 출력되어야 합니다:

The square of 5 is 25
The square of 6 is 36

결과가 나오지 않는다면 functions.sh 파일에 오타가 있는지 확인해 보세요.

변수 범위 이해하기

셸 스크립트에서 변수는 기본적으로 전역 (global) 변수입니다. 즉, 스크립트 어디에서나 접근할 수 있습니다. 하지만 local 키워드를 사용하면 해당 함수 내부에서만 접근 가능한 변수를 만들 수 있습니다. 이를 지역 범위 (local scope) 라고 합니다.

이 개념을 확인하기 위해 functions.sh 파일을 수정해 봅시다.

내용을 다음 코드로 업데이트하세요:

#!/bin/bash

## 전역 변수
GLOBAL_VAR="I'm global"

## 지역 변수를 사용하는 함수
demonstrate_scope() {
  local LOCAL_VAR="I'm local"
  echo "Inside function: GLOBAL_VAR = $GLOBAL_VAR"
  echo "Inside function: LOCAL_VAR = $LOCAL_VAR"
}

## 함수 호출
demonstrate_scope

echo "Outside function: GLOBAL_VAR = $GLOBAL_VAR"
echo "Outside function: LOCAL_VAR = $LOCAL_VAR"

이 스크립트에서 일어나는 일은 다음과 같습니다:

  • 전역 변수 GLOBAL_VAR를 정의합니다.
  • demonstrate_scope 함수 내부에서 local 키워드를 사용하여 지역 변수 LOCAL_VAR를 정의합니다.
  • 함수 내부에서 두 변수를 모두 출력합니다.
  • 함수 호출이 끝난 후, 함수 밖에서 다시 두 변수를 출력해 봅니다.

파일을 저장하고 실행합니다:

./functions.sh

다음과 유사한 결과가 출력될 것입니다:

Inside function: GLOBAL_VAR = I'm global
Inside function: LOCAL_VAR = I'm local
Outside function: GLOBAL_VAR = I'm global
Outside function: LOCAL_VAR =

함수 외부에서 접근했을 때 LOCAL_VAR가 비어 있는 것을 주목하세요. 이는 지역 변수가 정의된 함수 내부에서만 유효하기 때문입니다.

고급 함수 - ENGLISH_CALC

이제 셸 함수의 기초를 모두 배웠으므로, ENGLISH_CALC라는 조금 더 복잡한 함수를 만들어 보겠습니다. 이 함수는 두 개의 숫자와 하나의 연산 (plus, minus, times) 등 총 세 개의 인자를 받습니다.

파일 내용을 다음 코드로 교체하세요:

#!/bin/bash

ENGLISH_CALC() {
  local num1=$1
  local operation=$2
  local num2=$3
  local result

  case $operation in
    plus)
      result=$((num1 + num2))
      echo "$num1 + $num2 = $result"
      ;;
    minus)
      result=$((num1 - num2))
      echo "$num1 - $num2 = $result"
      ;;
    times)
      result=$((num1 * num2))
      echo "$num1 * $num2 = $result"
      ;;
    *)
      echo "Invalid operation. Please use 'plus', 'minus', or 'times'."
      return 1
      ;;
  esac
}

## 함수 테스트
ENGLISH_CALC 3 plus 5
ENGLISH_CALC 5 minus 1
ENGLISH_CALC 4 times 6
ENGLISH_CALC 2 divide 2 ## 에러 메시지가 표시되어야 함

이 함수의 구조를 살펴봅시다:

  • 입력값과 결과를 저장하기 위해 local 변수를 사용했습니다. 이는 전역 변수와의 충돌을 방지하는 좋은 습관입니다.
  • 다양한 연산을 처리하기 위해 case 문을 사용했습니다. 이는 다른 언어의 switch 문과 비슷합니다.
  • 유효한 연산에 대해서는 계산을 수행하고 결과를 출력합니다.
  • 잘못된 연산이 입력되면 에러 메시지를 출력하고 return 1을 실행합니다 (셸 스크립트에서 0 이 아닌 반환 값은 에러를 의미합니다).
  • 마지막 부분에서 유효하지 않은 연산을 포함하여 다양한 입력값으로 함수를 테스트합니다.

파일을 저장하고 실행합니다:

./functions.sh

다음과 같은 결과가 출력되어야 합니다:

3 + 5 = 8
5 - 1 = 4
4 * 6 = 24
Invalid operation. Please use 'plus', 'minus', or 'times'.

결과가 다르다면 functions.sh 파일에 오타가 없는지 다시 확인해 보세요.

요약

이 실습에서는 리눅스 셸 함수의 기초부터 고급 개념까지 살펴보았습니다. 우리가 배운 내용은 다음과 같습니다:

  1. 간단한 함수를 생성하고 호출하는 방법
  2. 함수의 매개변수를 다루는 방법
  3. echo 와 전역 변수를 사용하여 함수에서 값을 반환하는 방법
  4. 변수 범위를 이해하고 지역 변수를 사용하는 방법
  5. 산술 연산을 처리하는 복잡한 함수 구현 방법

셸 함수는 더 체계적이고 효율적이며 재사용 가능한 코드를 작성하는 데 매우 강력한 도구입니다. 복잡한 스크립트를 관리하기 쉬운 작은 조각으로 나누어 이해와 유지보수를 용이하게 해줍니다.

셸 함수를 마스터하면 리눅스 환경에서 더 정교한 스크립트를 작성하고 복잡한 작업을 효과적으로 자동화할 수 있습니다. 숙련도를 높이는 가장 좋은 방법은 연습입니다. 우리가 만든 함수를 수정해 보거나, 리눅스 작업 중에 마주치는 문제들을 해결하기 위한 자신만의 함수를 직접 만들어 보세요.