Function

function은 서브쉘을 생성하지 않고 명령을 수행함

쉘 명령 실행 우선순위
1) alias인지 판단
2) function인지 판단
3) 내장 명령인지 확인
4) 실행 프로그램인지 확인
function name {
commands
}
name() {
commands
}
위의 두가지 방법을 이용해서 함수를 정의할 수 있다.
두 번째 방법은 C 스타일의 함수 정의와 유사하지만, 함수 이름 정의 다음 괄호는 매개변수를 나타내는 것이 아닌 함수임을 나타낸다.
(항상 빈 괄호를 사용)

동일한 함수 이름으로 함수를 정의하게 되면, 오류 메시지 없이 이전의 함수 정의를 덮어쓴다.

bash에서 함수는 서브 쉘과 유사하게 동작한다.
함수 또한 종료 상태를 남기고 종료한다.
기본 종료 상태
$?를 이용해서 종료 상태를 남기기 때문에
함수 내부에서 수행되는 명령어가 실패하였어도 밖에서 이를 확인할려고 할 시, 확인할 수가 없다.
(함수가 성공적으로 종료되면, $?가 덮어씌워져 1의 상태로 기록된다.)
return 명령
서브쉘이 exit <num>을 이용해서 특정한 종료 상태를 만드는 것처럼 함수는 return <num>을 이용해서 특정한 종료 상태를 만든다.

- 함수가 완료되면 최대한 빨리 값을 저장하기(다른 값으로 변경되어 반환값을 잃어 버릴 수 있다.)
- 종료 상태는 0에서 255 사이의 정수 값이어야 함
함수 출력 사용하기
함수의 출력을 쉘 변수에 저장할 수 있다.
(위처럼 출력을 직접 쉘 변수로 받을 경우 0-255 범위 밖의 정수값도 받을 수 있다.)
function dbl {
read -p "Enter a value: " value # echo ,
echo $[ $value * 2 ]
}
result=$(dbl)
echo "Result is $result"
Enter a value: 1000
Result is 2000
함수에서 변수 사용
서브쉘을 실행할 때 매개변수를 전달하는 것과 동일하게
쉘 함수를 실행할 때, $0는 함수 이름을 $1~ 은 매개변수로 정의된다.    $#는 매개변수의 수를 저장한다.

함수는 자신의 매개변수 값에 대해 커맨드라인의 매개변수와 동일하게 사용하기 때문에 이를 사용할 수 없다.
만일 커맨드라인의 매개변수를 써야하는 경우, 다시 매개변수로 전달해야 함
#!/bin/bash
function addem {
if [ $# -eq 0 ] || [ $# -gt 2 ]; then
echo -1
elif [ $# -eq 1 ]; then
echo $[ $1 + $1 ]
else
echo $[ $1 + $2 ]
fi
}
echo -n "adding 10 and 15: "
value=$(addem 10 15)
echo $value
echo -n "just one number 10: "
value=$(addem 10)
echo $value
echo -n "No numbers: "
value=$(addem)
echo $value
adding 10 and 15: 25
just one number 10: 20
No numbers: -1
함수의 매개변수로 배열 사용
배열을 함수의 매개변수로 전달하게 되면, 첫 번째 값만 전달된다.
배열을 ${array[*]}를 이용해서 전체의 값을 매개변수로 전달하고,
함수 내부에서 새로운 배열 변수에 모든 매개변수를 재구성해야 한다.
#!/bin/bash
function arrayRec {
local newarray
newarray=(`echo "$@"`)
echo "The new array value is: ${newarray[*]}"
}
array=(1 2 3 4 5)
echo "The orig array value is: ${array[*]}"
arrayRec ${array[*]}
함수의 리턴값으로 배열 사용
매개변수로 배열을 전달할 때와 유사하게 개별 배열 값을 출력하기 위해 적절하게 echo를 사용한다.
#!/bin/bash
function arrayRet {
local origarray
local newarray
local elements
local i
origarray=($(echo "$@")) # receive array
newarray=($(echo "$@"))
elements=$[ $# - 1 ]
for (( i=0; i<=$elements; i++ ))
{
newarray[$i]=$[ ${origarray[$i]} * 2 ]
}
echo ${newarray[*]} # return array
}
array=(1 2 3 4 5)
echo "The orig array is: ${array[*]}"
arg1=$(echo ${array[*]})
result=($(arrayRet $arg1))
echo "The new array is: ${result[*]}"
커맨드 라인에서 함수 정의 및 사용
- 한줄에 정의하기
function divem { echo $[ $1 / $2 ]; }
한줄 안에 모든 function 정의 코드를 작성할 수 있다.
단, 각 명령을 어디에서 구분해야 하는지 알 수 있도록 각 명령의 끝에 세미콜론 ' ; '을 사용해서 표기
- 여러 줄에 걸쳐서 함수를 정의
쉘 스크립트와 동일하게 작성한다(세미콜론 사용할 필요 없음)
쉘 프롬프트에서 더 많은 명령을 요구하는 보조 쉘 프롬프트(PS2)를 사용한다.

커맨드라인에서 함수를 만들어 사용할 때, 내장 명령 혹은 다른 명령과 같은 이름의 함수가 사용중이면,
함수보다 원래 명령보다 우선된다.(기존의 명령이 가려짐)
unset -f <function_name>
unset -f 옵션을 사용해 함수 정의를 해제할 수 있다.