매개변수와 반환값
함수가 제 역할을 하려면 외부에서 값을 받고, 결과를 돌려줄 수 있어야 합니다. 인수를 받지 못하면 "안녕하세요"만 출력하는 함수에서 벗어날 수 없고, 결과를 돌려주지 못하면 함수 안에서 계산한 값을 쓸 수 없습니다.
함수 안의 매개변수 변수
함수를 호출할 때 전달한 인수는 함수 안에서 $1, $2, $3 ... 으로 받습니다. PART 03에서 배운 스크립트 매개변수와 이름이 같습니다. 중요한 점은 이 두 가지가 서로 독립적이라는 것입니다. 함수 안에서 $1은 스크립트에 전달된 첫 번째 인수가 아니라, 그 함수에 전달된 첫 번째 인수입니다.
#!/bin/bashshow_args() { echo "함수 인수 개수: $#" echo "첫 번째 인수: $1" echo "두 번째 인수: $2" echo "모든 인수: $@"}# 스크립트 실행: ./test.sh apple banana cherryecho "스크립트 첫 번째 인수: $1" # appleshow_args "X" "Y" "Z" # 함수에 별도 인수 전달echo "스크립트 첫 번째 인수: $1" # 여전히 apple (영향 없음)
$#은 인수 개수, $@은 모든 인수를 공백으로 구분해서 나열합니다. $*도 비슷하지만, 큰따옴표로 감쌌을 때 차이가 납니다. "$@"은 각 인수를 개별 문자열로 유지하고, "$*"는 모든 인수를 하나의 문자열로 합칩니다. 공백이 포함된 인수를 다룰 때는 "$@"이 안전합니다.
return 명령어
함수가 성공했는지 실패했는지를 알리는 방법이 return입니다. 0은 성공, 1~255는 실패를 의미합니다. 호출 후 $?로 확인합니다.
#!/bin/bashis_even() { if (( $1 % 2 == 0 )); then return 0 # 성공 (짝수) else return 1 # 실패 (홀수) fi}is_even 4echo "4는 짝수인가? $?" # 0is_even 7echo "7은 짝수인가? $?" # 1
return의 한계가 있습니다. 0부터 255 사이의 정수만 전달할 수 있습니다. 문자열을 돌려주거나, 255를 넘는 숫자를 돌려주려면 다른 방법이 필요합니다.
문자열 반환: echo + 명령 치환
문자열이나 큰 숫자를 돌려줄 때는 echo로 출력하고, 호출 쪽에서 명령 치환($(...))으로 받습니다.
#!/bin/bashto_uppercase() { echo "$1" | tr '[:lower:]' '[:upper:]'}get_greeting() { local name="$1" echo "안녕하세요, ${name}님!"}result=$(to_uppercase "hello world")echo "$result" # HELLO WORLDmsg=$(get_greeting "철수")echo "$msg" # 안녕하세요, 철수님!
함수 안에서 echo로 출력한 내용이 $(...)로 캡처됩니다. 주의할 점은 함수 안에서 디버그 메시지를 echo로 출력하면 그것도 함께 캡처된다는 것입니다. 디버그 출력은 >&2로 표준 오류로 보내는 것이 좋습니다.
get_info() { echo "디버그: 함수 시작" >&2 # 표준 오류로 → 캡처되지 않음 echo "실제 반환값" # 표준 출력으로 → 캡처됨}result=$(get_info)# 터미널에는 "디버그: 함수 시작"이 보이고# result 변수에는 "실제 반환값"만 담김
실습: 두 수의 최대값 반환 함수, 문자열 반복 함수
#!/bin/bash# 새 파일: func_return.sh# 두 수 중 최대값을 반환하는 함수max_of() { if (( $1 >= $2 )); then echo "$1" else echo "$2" fi}# 문자열을 N번 반복하는 함수repeat_str() { local str="$1" local count="$2" local result="" local i for (( i = 0; i < count; i++ )); do result="${result}${str}" done echo "$result"}# 파일이 읽기 가능한지 확인하는 함수 (return 방식)is_readable() { if [[ -r "$1" ]]; then return 0 else return 1 fi}# --- 실행 ---bigger=$(max_of 42 17)echo "42와 17 중 큰 수: $bigger"bigger=$(max_of 5 99)echo "5와 99 중 큰 수: $bigger"line=$(repeat_str "-" 30)echo "$line"star_line=$(repeat_str "* " 10)echo "$star_line"if is_readable "/etc/hostname"; then echo "/etc/hostname 읽기 가능"else echo "/etc/hostname 읽기 불가"fi
실행 결과는 다음과 같습니다.
42와 17 중 큰 수: 42
5와 99 중 큰 수: 99
------------------------------
* * * * * * * * * *
/etc/hostname 읽기 가능
max_of 함수는 echo로 값을 출력하고 호출 쪽에서 $(max_of ...)로 받습니다. repeat_str 함수도 같은 패턴입니다. is_readable 함수는 참/거짓만 전달하면 되므로 return을 사용했습니다. 용도에 따라 두 방식을 적절히 선택합니다.