[Shell Script] Functions - 1
Functions
{ ;}, ()를 이용해 명령 그룹을 만들면 같은 context에서 실행되어 명령 그룹 전체가 하나의 명령처럼 실행되는 것과 같은 화가를 가진다.
따라서 명령 그룹에 이름을 붙임으로써 함수를 정의하면 일반 명령과 동일하게 사용할 수 있다.
{ ;}는 현재 shell에서, ()은 subshell에서 실행되므로 보통 { ;}를 사용하여 함수를 정의한다.
# 파이프로 인해 subshell에서 실행되어 echo $var는 값이 표시되지 않는다.
echo hello world | read var; echo "$var"
# 명령 그룹을 만들면 read, echo 명령이 같은 context에서 실행되어 값이 표시된다.
echo hello world | { read var; echo "$var" ;}
함수 사용 방법
일반 명령과 동일하며, return 명령으로 종료 상태 값을 지정할 수 있다. subshell에서는 정의했던 함수를 별다른 설정 없이 사용할 수 있으나, 새로운 프로세스에서도 사용하기 위해서는 export -f를 이용해 함수를 export 해야 한다.
함수 정의 방법
Shell은 전달된 인자가 함수 내에서 특수 변수($1, $2, $3……)에 자동으로 할당되기 때문에 함수 정의 시 매개변수를 적지 않는다.
함수명에는 메타문자나 quotes 등은 사용할 수 없고, 외부 명령이나 alias와 같은 이름을 사용하는 경우에는 syntax error가 발생한다. 단, bash의 경우 function 키워드를 붙임으로써 에러를 방지할 수 있다.
# 문법
function_name () {
commands
};
# bash에서 허용
function function_name() {
commands
}
# 정의된 함수 내용 보기
declare -f <function_name>
# 현재 쉘에 정의된 모든 함수명 보기
declare -F
compgen -A function
# 특정 함수의 정의 여부 확인
declare -F <function_name>
# 정의된 함수 삭제
unset -f <function_name>
함수는 실행하기 전에 정의되어 있어야 한다.
foo1 # 여기서는 foo1 함수 정의가 안되어있기 때문에 실행할 수 없다.
foo1() {
echo "foo1"
foo2
}
# 여기서 foo1 함수를 실행할 수 있지만 foo1 함수내에 있는
foo1 # foo2 함수를 실행할수 없으므로 오류가 발생한다.
foo2() {
echo "foo2"
}
foo1 # 여기서는 오류없이 foo1, foo2 함수가 모두 실행된다.
조건에 따라 다른 함수를 정의할 수 있다.
아래 스크립트는 KSH_VERSION이라는 변수가 설정되어 있으면, 첫번째 puts 함수가 정의되고, 그렇지 않으면 두 번째 puts 함수가 정의된다.
if test -n "$KSH_VERSION"; then
puts() {
print -r -- "$*"
}
else
puts() {
printf '%s\n' "$*"
}
fi
변수는 기본적으로 global하다.
변수는 source 한 파일을 포함해 현재 스크립트 내에서 global 하다.
local 명령으로 지역변수를 설정할 수 있다.
local과 declare은 같은 기능을 한다. 단, local은 global scope에서 사용할 수 없다. 또한 함수 내에서 declare가 사용되면 local과 동일하다.
💡 local 변수는 unset 시 global 변수가 된다.
scope을 유지하면서 변숫값을 초기화할 때는 ""으로 초기화해야 한다.
Shell은 dynamic scoping을 사용한다.
함수에서 local로 선언한 변수는 child 함수에서 읽고 쓸 수 있다. child 함수에서 변경된 값은 parent 함수에 적용된다.
💡 dynamic scoping
함수 f1이 실행 중일 때 함수 f2에서 f1의 지역변수에 접근하는 것. sh, bash, powershell, emacs lisp 같은 언어에서 사용되고 있다.
보통 프로그래밍 언어는 lexical scoping(static scoping)을 사용하여 f2은 f1의 지역 변수에 접근할 수 없다.
참고 문서
https://mug896.github.io/bash-shell/functions.html