셸 함수 기초

ShellBeginner
지금 연습하기

소개

스크립트를 작성하다 보면 같은 코드 블록을 여러 번 반복해야 하는 경우가 많습니다. 이 코드를 매번 다시 작성하거나 복사해서 붙여넣는 대신 함수를 사용할 수 있습니다.

함수는 특정 작업을 수행하는 이름이 지정된 코드 블록입니다. 함수를 한 번 정의하면 필요할 때마다 호출할 수 있습니다. 따라서 스크립트를 다음과 같이 작성할 수 있습니다.

  • 모듈화: 읽고 관리하기 쉽습니다.
  • 재사용 가능: 한 번 작성하고 여러 번 사용할 수 있습니다.
  • 유지 관리 용이: 로직을 변경해야 할 때 한 곳만 수정하면 됩니다.

모든 코드가 위에서 아래로 이어지는 긴 블록 하나에 들어 있으면 규모가 큰 스크립트의 동작을 파악하기 어려워집니다. 스크립트를 함수로 나누는 것은 "빠르게 작성한 셸 해킹 코드"를 "유지 관리 가능한 자동화"로 발전시키는 첫 단계 중 하나입니다.

이 실습에서는 함수를 사용해 스크립트를 다시 구성하는 기본 방법을 배웁니다. 다음 작업을 수행합니다.

  1. 기본 스크립트를 만듭니다.
  2. greet_user라는 함수를 정의합니다.
  3. 함수를 호출하여 실행합니다.
  4. 매개변수 (인수) 를 받을 수 있도록 함수를 개선합니다.

스크립트 파일 만들기

먼저 작업 공간을 준비합니다. 코드를 저장할 functions.sh 파일을 만듭니다.

이 단계에서 스크립트 파일은 아직 단순한 컨테이너입니다. 이 실습에서 중요한 변화는 파일 자체가 아니라, 스크립트를 위에서 아래로 이어지는 긴 순서 하나가 아닌 이름이 지정된 여러 부분으로 구성할 수 있다는 점입니다.

먼저 프로젝트 디렉터리로 이동한 다음 파일을 만듭니다.

cd ~/project
touch functions.sh

그런 다음 텍스트 편집기에서 파일을 열어 표준 Shebang 헤더를 추가합니다.

nano functions.sh

파일의 맨 위에 다음 줄을 추가합니다.

#!/bin/bash

파일을 저장하고 (Ctrl+O, Enter) 종료합니다 (Ctrl+X).

마지막으로 나중에 스크립트를 실행할 수 있도록 실행 권한을 부여합니다.

chmod +x functions.sh

이제 코드를 작성할 준비가 되었습니다.

함수 정의하기

이제 greet_user라는 함수를 정의합니다.

Bash 에서는 함수 이름 뒤에 괄호 ()를 쓰고, 코드 블록을 중괄호 {}로 감싸 함수를 정의합니다.

함수는 명령 블록에 재사용 가능한 이름을 부여합니다. 셸 스크립트의 가독성이 높아지는 이유도 여기에 있습니다. 스크립트 곳곳에서 원시 명령을 보는 대신 backup_files, check_disk, greet_user처럼 동작을 나타내는 의미 있는 이름을 볼 수 있습니다.

문법은 다음과 같습니다.

function_name() {
  ## Commands to execute
}

스크립트를 다시 엽니다.

nano functions.sh

Shebang 줄 아래에 다음 함수 정의를 추가합니다.

#!/bin/bash

greet_user() {
  echo "Hello"
}

중요: 이 시점에는 함수를 정의하기만 했습니다. 스크립트에 함수를 실제로 실행하라고 지정하지는 않았습니다. 지금 스크립트를 실행하면 아무 동작도 일어나지 않습니다. 초보자가 자주 혼동하는 부분인데, 함수를 정의한다고 해서 함수가 자동으로 실행되지는 않습니다.

이 구분이 중요한 이유는 셸 스크립트가 순서대로 읽히고 실행되기 때문입니다. 함수 정의는 Bash 에 함수의 동작을 알려주지만, 함수 이름을 나중에 호출하기 전까지 함수 본문은 실행되지 않습니다.

지금은 저장하고 종료합니다.

함수 호출하기

함수 내부의 코드를 실행하려면 함수를 "호출"해야 합니다. Bash 에서는 새 줄에 함수 이름을 적는 것만으로 함수를 호출할 수 있습니다. 호출할 때 괄호를 사용할 필요는 없습니다.

많은 프로그래밍 언어가 함수 호출에 괄호를 사용하기 때문에 초보자에게는 이 방식이 낯설 수 있습니다. Bash 에서는 greet_user 자체가 명령처럼 처리됩니다. 해당 이름의 함수가 있으면 Bash 가 함수 본문을 실행합니다.

스크립트를 엽니다.

nano functions.sh

파일 맨 아래에 함수 호출을 추가합니다.

#!/bin/bash

greet_user() {
  echo "Hello"
}

## The Main Logic starts here
greet_user

저장하고 종료합니다.

이제 스크립트를 실행합니다.

./functions.sh

스크립트가 실행되면 셸은 greet_user 명령을 보고 함수 정의를 찾은 다음 echo "Hello"를 실행하고 계속 진행합니다.

이런 의미에서 함수는 현재 스크립트나 셸 세션 안에서만 존재하는 사용자 정의 명령과 비슷하게 동작합니다. 따라서 함수는 작은 셸 명령을 조합해 더 높은 수준의 동작을 만들 때 유용합니다.

다음 출력이 표시되어야 합니다.

Hello

함수에 인수 전달하기

항상 똑같은 작업만 수행하는 함수 (예: "Hello" 출력) 는 활용도가 제한적입니다. 함수의 활용도를 높이려면 함수에 데이터를 전달할 수 있습니다. 이 데이터를 인수라고 합니다.

함수 내부에서는 스크립트 인수와 마찬가지로 $1, $2 같은 특수 변수를 사용해 인수에 접근할 수 있습니다.

  • $1은 함수에 전달된 첫 번째 인수를 나타냅니다.
  • $2는 두 번째 인수를 나타내며, 이후에도 같은 방식으로 이어집니다.

이 값들은 함수가 실행되는 시점에 스크립트가 사용하는 위치 매개변수와는 별개입니다. 즉, 함수는 자체적인 작은 입력 인터페이스를 가질 수 있으므로 서로 다른 값을 사용해 쉽게 재사용할 수 있습니다.

특정 이름을 인사하도록 함수를 수정합니다.

1 단계: 함수 정의 수정하기

파일을 엽니다.

nano functions.sh

greet_user 함수에서 고정 문자열 대신 $1을 사용하도록 변경합니다.

greet_user() {
  echo "Hello $1"
}

2 단계: 함수 호출 수정하기

이제 함수가 인수를 받도록 변경했으므로 함수를 호출할 때 인수를 제공해야 합니다.

호출 부분을 greet_user에서 greet_user "LabEx"로 변경합니다.

이제 파일은 다음과 같아야 합니다.

#!/bin/bash

greet_user() {
  echo "Hello $1"
}

greet_user "LabEx"

저장하고 종료합니다.

3 단계: 스크립트 테스트하기

스크립트를 다시 실행합니다.

./functions.sh

이제 다음 출력이 표시되어야 합니다.

Hello LabEx

입력을 받아 처리하는 사용자 정의 명령을 만든 셈입니다. 스크립트의 뒤쪽에서 greet_user "Alice" 또는 greet_user "Bob"을 호출하면 전달한 이름에 맞게 동작합니다.

요약

이 실습에서는 Bash 함수의 기초를 배웠습니다.

  1. 정의: name() { ... } 형식으로 이름이 지정된 코드 블록을 만듭니다.
  2. 호출: 함수 이름을 입력해 함수를 실행합니다.
  3. 인수: 함수에 데이터를 전달하고 $1, $2 등을 통해 데이터에 접근합니다.

함수는 복잡한 스크립트를 구성하는 기본 요소입니다. 함수를 사용하면 로직을 정리하고 반복을 줄이며 코드를 더 읽기 쉽고 유지 관리하기 쉽게 만들 수 있습니다.