웹사이트 검색

Bash 함수에 대한 부드러운 소개


Bash 스크립팅을 막 시작했다면, 스크립트에서 같은 명령을 반복해서 사용하는 경우가 많을 수 있습니다. 하지만 더 나은 방법이 있습니다. 여기서 'DRY'가 무엇을 의미하는지, 그리고 이를 위해 함수를 어떻게 사용해야 하는지 설명하겠습니다.

제가 윈도우에서 처음으로 프로그램을 작성했을 때, 그것은 배치 스크립트였습니다. 저는 거의 즉흥적으로 작성했고, 최소한의 이해만으로 아주 문자 그대로의 지시문을 작성했으며, GOTO 문을 여기저기 넣고, 스크립트를 읽기 어렵게 만들 정도로 같은 내용을 반복했습니다.

프로그래밍에서 DRY는 '같은 것을 반복하지 말라'는 뜻입니다. 함수를 사용하는 것이 이를 실현하는 방법이며, 제가 그 방법을 보여드리겠습니다.

Bash 함수 입문

저는 시각적인 학습자라서 기술적인 세부사항을 보기 전에 주제를 보는 것이 도움이 된다고 믿어요. 그래서 여기에 한 함수가 있습니다:

foo() {
  echo "Hello, World!"
}

'foo'는 함수 이름이며, 이것이 우리가 함수를 호출(call)하는 방법입니다:

foo
foo

함수를 두 번 호출한 것을 눈치채셨나요? 이것이 함수의 본질입니다: 코드를 'DRY'하게 만들기 위한 재사용 가능한 조각들입니다.

우리는 또한 "function" 키워드를 사용하여 함수를 정의할 수 있지만, 그렇게 하면 다른 쉘에서는 스크립트를 사용할 수 없습니다:

function foo () {
   echo "Hello, World!"
}

계속해서. 좀 더 현실적인 예는 유용한 명령어를 감싸는 것입니다:

backup() {
    cp "foo.txt" "foo.txt.backup-$(date +%Y%m%d)"
}

이 함수는 "foo.txt"라는 파일 이름에 단순히 "backup"과 날짜를 덧붙여 파일을 백업합니다. 다음 섹션에서는 이 함수를 재사용 가능하게 만들 것입니다.

함수는 훨씬 더 클 수 있으며 여러 줄에 걸쳐 작성될 수 있습니다. 함수를 작은 재사용 가능한 스크립트나 명령어로 생각하면 됩니다.

함수에 인수 전달하기

함수는 값들을 전달할 수 있을 때만 거의 유용하며, 우리는 그렇게 할 수 있습니다—이를 매개변수나 인수라고 부릅니다.

이 용어들 간의 차이는 미미합니다. 저는 이것들을 인수라고 부르겠지만, Bash 매뉴얼에서는 이를 매개변수라고 부를 수도 있습니다.

다시 말하지만, 예시는 처음에 제시하는 것이 가장 좋습니다:

foo() {
    echo "${1}" "${2}"
}

"$ {1}"과 "$ {2}"는 각각 첫 번째와 두 번째 인수입니다. 이를 "foo"에 다음과 같이 전달합니다:

foo "Hello, " "World!"
foo "Hello, " "Universe!"

단어의 경계를 정의하려면 단어 주위에 "따옴표"를 사용하세요. "Hello"에는 쉼표와 공백도 포함되어 있다는 것을 눈치채셨나요? 이렇게 따옴표를 사용하면 Bash에서 단어의 경계가 명확해집니다.

이것들을 문자열이라고 하고, 문자열을 깔끔하게 바꾸는 방법을 다룬 더 고급 글도 있습니다.

어쨌든, 다시 함수로 돌아가 보겠습니다. "$1"과 "$2"는 Bash 용어로 위치 매개변수라고 불립니다(즉, 위치가 있는 매개변수). 인수에 접근하는 방법은 여러 가지가 있으며, 일부는 더 고급이지만, "$1"과 "$2"면 초보자에게 충분합니다.

실제 예에서 인수를 사용해 봅시다:

backup() {
    cp "${1}" "${1}.backup-$(date +%Y%m%d)"
}

이것은 이전의 '백업' 기능을 개선한 것입니다. 단 하나의 매개변수만 필요합니다: 파일 이름(또는 경로). 이제 이 함수는 원하는 모든 파일을 백업할 수 있어 사하라 사막보다 훨씬 건조합니다.

큰따옴표("")로 "$ {1}"을 감싸면 Bash가 할당된 값으로 이를 대체(확장)할 수 있습니다. 작은따옴표('')는 다르게 작동하며 문자열을 그대로 리터럴로 만듭니다:

backup() {
    echo '${1}' '${1}.backup-$(date +%Y%m%d)'
}
backup "foo.txt"

"cp"를 "echo"로 변경했으므로 "${1}" 인수가 어떻게 보이는지 확인할 수 있습니다. 이제 더 이상 변수는 아니고, 지정한 그대로의 리터럴 값입니다. 변수에 대한 자세한 내용은 아래에서 다룹니다.

코드를 더 읽기 쉽게 만들어 줄 작은 개념 하나를 더 소개하고 싶습니다(매우 중요함):

backup() {
    local file_path="${1}"
    cp "$file_path" "$file_path.backup-$(date +%Y%m%d)"
}

"local file_path=${1}"은 변수 할당이라고 합니다. 변수는 값을 저장하는 장소입니다. 우리는 "file_path"라는 변수를 만들고 거기에 "${1}"(함수 인수)을 저장했습니다. 이제 "file_path"는 "${1}"과 같으며, 우리는 명령어에서 그것을 사용합니다.

변수 이름을 이렇게 사용하여 인자가 무엇인지 설명하세요. 나중에 자신이 코드를 볼 때 즉시 이해할 수 있어 고마워할 것입니다.

함수에서 값 반환

Bash 함수에서 값을 반환하는 것은 다른 언어와 약간 다릅니다. Bash에서는 오직 종료 코드만 반환할 수 있으며, 이는 명령어의 성공 상태를 나타내는 숫자입니다. 예를 들어:

foo() {
  return 0
}

foo && echo "success"

"&&"는 "foo"가 성공적인 종료 코드("0")를 반환할 경우에만 "success"를 "echo"합니다.

실패한 종료 코드(예: 명령어가 실패한 경우)를 살펴보겠습니다:

foo() {
  return 1  # Non-zero means unsuccessful.
}

foo && echo "success"  # Doesn't echo "success".

간단히 말해, Bash 함수의 반환 값은 오직 종료 코드용입니다.

계속해서, 함수에서 유용한 값을 얻어봅시다.

더 향상된 Bash 실력을 위해 뉴스레터를 구독하세요

더 향상된 Bash 실력을 위해 뉴스레터를 구독하세요

구독함으로써 뉴스레터 및 마케팅 이메일 수신에 동의하며, Valnet의 이용 약관과 개인정보 처리방침을 확인하고 동의하게 됩니다. 언제든지 구독을 취소할 수 있습니다.

Bash에서 모든 출력은 본질적으로 문자열입니다. 명령어가 결과(숫자나 텍스트)를 출력할 때, 그것은 문자열입니다. Bash 출력을 메시지라고 생각해보세요: 명령어에게 무엇을 하라고 요청하면, 명령어가 메시지로 답합니다. 함수에서 값을 반환하고 싶을 때는 "echo"로 메시지를 출력합니다:

foo() {
  echo "Hello, World!"
}

명령어(예: "echo")가 실패하면, 함수는 암시적으로 종료 코드를 반환하지만, 원하는 대로 사용자 지정 종료 코드를 반환할 수 있습니다.

foo() {
  echo "Hello, World!"
  return 0
}

결과에 대해 다른 명령어처럼 뭔가를 해봅시다:

foo() {
  echo "Hello, World!"
  return 0 # This won't be processed by "tr".
}
foo | tr '[[:lower:]]' '[[:upper:]]'

"tr"는 "foo"에서 출력된 "Hello, World!"를 대문자 문자열로 바꿉니다. 이는 "echo"를 사용하여 값을 반환하고 다른 명령처럼 그것을 처리할 수 있음을 보여줍니다.

요점을 분명히 하기 위해, 우리는 어떤 명령의 출력에도 직접 작용할 수 있습니다:

foo() {
  echo "Hello, World!" | tr '[[:lower:]]' '[[:upper:]]'
}
foo | sed 's/WORLD/UNIVERSE/'

여기서 함수는 "Hello, World!"를 출력하고, "tr"은 이를 대문자로 변환합니다. 함수 외부에서는 결과를 "sed"에 파이프하여 "WORLD"를 "UNIVERSE"로 바꿨습니다.


Bash 함수는 본질적으로 명령어를 감싸서 재사용할 수 있는 래퍼입니다. 이를 사용하여 복잡한 명령 파이프라인을 정의하거나 일부 자세한 작업을 수행하고 결과를 출력할 수 있습니다. 함수는 명령어처럼 인수를 받아들이고 종료 코드를 제공합니다.

Bash 함수를 가장 자주 사용하게 될 것은 쉘 작업을 더 쉽게 만들기 위해서입니다. 복잡한 명령어 파이프라인을 매번 입력하는 대신, 함수를 만들고 인수를 전달하세요. 이러한 함수들은 bashrc 파일에 추가하면 다른 명령어처럼 쉘에서 사용할 수 있습니다. 또는 PATH에 있는 스크립트 안에서 사용할 수도 있습니다.

관련기사