[쉘 스크립트] 쉘 스크립트 기초 - 함수 (7)
카테고리: Linux
태그: Linux
🎯함수
함수 정의
bash 쉘 스크립트에서 함수를 만들기 위해 사용할 수 있는 형식은 두 가지가 있다.
# 방법 1.
function name {
commands
}
# 방법 2.
name() {
commands
}
name속성은 함수에 지정할 고유한 이름을 정의한다. 스크립트에서 사용자가 정의하는 함수에는 고유한 이름을 지정해야 한다.commands는 함수를 구성하는 하나 이상의 bash 쉘 명령이다. 함수를 호출할 때 bash 쉘은 보통의 스크립트처럼 함수에 나타나는 순서로 각 명령을 실행한다.
함수 호출
# 스크립트
#!/bin/bash
func1
function func1 {
echo "This is an example of a function"
}
count=1
while [ $count -le 5 ]
do
func1
count=$[ $count + 1 ]
done
echo "This is the end of the loop"
func1
echo "Now This is the end of the script"
# 실행 결과
func1: command not found
This is an example of a function
This is an example of a function
This is an example of a function
This is an example of a function
This is an example of a function
This is the end of the loop
This is an example of a function
Now This is the end of the script
- 스크립트에서 func1 함수 이름을 참조할 때마다 bash 쉘은 func1 함수안에 정의된 명령을 실행한다.
- 함수가 정의되기 전에 이를 사용하려고 하면 오류 메시지가 나타난다.
함수 리턴
bash 쉘에서 함수의 종료 상태를 만드는 방법에는 세 가지가 있다.
- 기본 종료
- return 명령 사용하기
- 함수 출력 이용하기
기본 종료
기본적으로 함수의 종료 상태는 함수의 마지막 명령이 돌려주는 종료 상태다.
# 스크립트
#!/bin/bash
func1() {
echo "trying to display a non-existent file"
ls -l badfile
}
echo "testing the function: "
func1
echo "The exit status is: $?"
# 실행 결과
testing the function:
trying to display a non-existent file
ls: cannot access 'badfile': No such file or directory
The exit status is: 2
- 함수의 마지막 명령이 실패했기 때문에 함수의 종료 상태는 0이 아니다.
- 함수의 종료 상태를 결정하는데에
echo문은 영향을 주지 않는다. 오직 마지막 명령의 결과가 함수의 종료 상태를 의미한다.
return 명령 사용하기
bash쉘은 함수가 특정한 종료 상태를 돌려줄 수 있도록 return 명령을 사용할 수 있다. return 함수로 종료 상태를 정의하는 단일한 정수값을 사용한다.
# 스크립트
#!/bin/bash
function dbl {
read -p "Enter a value: " value
echo "doubling the value"
return $[ $value * 2 ]
}
dbl
echo "The new value is $?"
# 실행 결과
Enter a value: 2
doubling the value
The new value is 4
- dbl 함수는 사용자가 입력한 정수값을 $value 변수에 저장하고 이를 두 배로 만든다.
return명령은 함수의 종료 상태를 돌려주므로 스크립트는 $? 특수 변수의 결과로 입력한 값의 2배한 결과를 표시한다.return명령을 사용할 때에 주의할 점이 몇 가지 있다.- $? 변수를 사용하여 함수의 값을 얻기 전에 다른 명령을 실행하면 함수의 반환값을 잃어버리게 된다. $? 변수는 마지막으로 실행된 명령의 종료 상태를 돌려준다는 점을 잊지 말아야 한다.
- 종료 상태는 0에서 255의 범위 안에 있어야 한다. 종료 상태는 256보다 작아야 하므로 함수의 결과는 256보다 작은 정수값이어야 한다. 그 이상의 값은 255로 모듈러 연산한 값으로 변환된다.
함수 출력 이용하기
명령의 출력을 쉘 변수에 저장할 수 있는 것처럼 함수의 출력도 쉘 변수에 저장할 수 있따. 변수에서 나온 어떤 유형의 출력이든 변수에 할당하면 된다. 이 방법은 return 명령에서 256 이상의 값을 반환할 수 없는 한계를 보완할 수 있다.
# 스크립트
#!/bin/bash
function dbl {
read -p "Enter a value: " value
echo $[ $value * 2 ]
}
result=$(dbl)
echo "The new value is $result"
# 실행 결과
Enter a value: 2
The new value is 4
- 새로운 함수는 이제 계산 결과를 표시하는 echo 문을 사용한다. 스크립트는 답을 받기 위해 종료 상태 대신 dbl 함수의 출력을 저장한다.
- read 명령에서 사용자에게 묻는 짧은 메시지는 출력의 결과에 포함되지 않는다.
함수 매개변수
함수는 커맨드라인에서 함수에 전달되는 매개변수를 대신하기 위한 표준 매개 변수 환경 변수를 사용할 수 있다. 예를 들어, 함수의 이름은 $0 변수로 정의되고 함수의 커맨드라인에 있는 모든 매개변수는 $1, $2와 같은 변수로 정의된다. 또한 함수에 전달된 매개변수의 수를 결정하기 위한 특수한 변수 $#도 사용할 수 있다.
# 스크립트
#!/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 "Let's try adding just one number: "
value=$(addem 10)
echo $value
echo -n "Now trying adding no numbers: "
value=$(addem)
echo $value
echo -n "Finally, try adding three numbers: "
value=$(addem 10 15 20)
echo $value
# 실행 결과
Adding 10 and 15: 25
Let's try adding just one number: 20
Now trying adding no numbers: -1
Finally, try adding three numbers: -1
- 스크립트에 있는 addem 함수는 먼저 스크립트가 전달한 매개변수의 수를 확인 한다.
- 매개변수가 없거나 매개변수가 2개 보다 많다면 addem 함수는 -1을 돌려준다.
- 매개변수가 하나만 있다면 addem 함수는 이 매개변수를 2배로 만들어서 결과값으로 사용한다.
- 매개변수가 2개 있다면 addem 함수는 두 변수를 더해서 결과값으로 사용한다.
함수에서 변수의 범위
변수의 범위란, 변수가 보이는 곳을 뜻한다. 함수에 정의된 변수는 두 종류로 나뉜다.
- 전역 변수
- 지역 변수
전역 변수
전역 변수는 쉘 스크립트 안이라면 어디서나 쓸 수 있는 변수다. 기본적으로 스크립트에서 정의한 모든 변수는 전역 변수다. 스크립트의 메인 부분에서 변수를 정의했는지 함수 안에서 변수를 정의했는지는 중요하지 않다.
# 스크립트
#!/bin/bash
function dbl {
value=$[ $value * 2 ]
}
read -p "Enter a value: " value
dbl
echo "The new value is: $value"
# 실행 결과
Enter a value: 2
The new value is: 4
- value 변수는 함수 밖에서 정의되었고 함수 밖에서 값이 할당되었다.
- dbl 함수가 호출될 때 함수 밖에서 정의된 value 변수가 참조된다.
- 함수 안에서 value 변수가 재 할당된다.
- 함수 밖에서 재 할당된 value 변수를 참조한다.
지역 변수
함수에서 전역 변수를 사용하는 대신 함수 안에서 사용되는 모든 변수를 지역 변수로 선언할 수 있다. 이를 위해서는 변수 선언 앞에 local 키워드를 사용하면 된다.
# 스크립트
#!/bin/bash
function func1 {
local temp=$[ $value + 5 ]
result=$[ $temp * 2 ]
echo "Here is inside the function....."
echo "The temp is $temp"
}
temp=4
value=6
func1
echo "Here is outside the function....."
echo "The result is $result"
echo "The temp is $temp"
# 실행 결과
Here is inside the function.....
The temp is 11
Here is outside the function.....
The result is 22
The temp is 4
func1 함수 안에서 $temp 변수를 변경해도 메인 스크립트 안에 있는 $temp 변수에 할당된 값에는 영향을 주지 않았다.
라이브러리 만들기
bash 쉘은 함수에 대한 라이브러리 파일을 만들어서 어떤 스크립트에서나 해당 라이브러리 파일을 가져와 쓸 수 있도록 기능을 제공한다. 다음은 간단한 라이브러리 파일을 만들고 이를 활용하는 예제이다.
- 먼저 세 가지 간단한 함수를 정의하는 myfunc라는 간단한 공용 라이브러리 파일을 만든다.
function add { echo $[ $1 + $2 ] } function mul { echo $[ $1 * $2 ] } function div { if [ $2 -ne 0 ] then echo $[ $1 / $2 ] else echo -1 fi } - 다음 단계는 스크립트 파일에 myfunc 라이브러리 파일을 포함시키는 것이다. 하지만 문제가 있다.
- 쉘 함수의 범위는 이를 정의한 쉘 세션 안에서만 유효하다.
- myfunc 스크립트를 실행시킨다면 쉘은 새로운 쉘을 만들고 그 새로운 쉘에서 스크립트를 실행한다.
# 스크립트 #!/bin/bash ./myfunc result=$(add 10 15) echo "The result is $reulst" # 실행 결과 add: command not found The result is - 이 문제를 해결할 방법은
source명령이다.source명령은 새로운 쉘을 실행시키는 대신 현재 쉘 안에서 명령을 실행시킨다. - 쉘 스크립트 안에서 라이브러리 파일의 스크립트를 실행하기 위해
source명령을 사용한다. 이렇게 하면 스크립트 안에서 함수를 사용할 수 있다.# 스크립트 #!/bin/bash source ./myfunc value1=10 value2=5 result1=$(add $value1 $value2) result2=$(mul $value1 $value2) result3=$(div $value1 $value2) echo "The result of adding them is: $result1" echo "The result of multiplying them is: $result2" echo "The result of dividing them is: $result3" # 실행 결과 The result of adding them is: 15 The result of multiplying them is: 50 The result of dividing them is: 2
- 스크립트는 myfunc 라이브러리 파일에 정의된 함수를 성공적으로 사용했다.
커맨드라인에서 함수 만들기
첫 번째 방법은 함수 정의를 모두 한 줄에 놓는 것이다. 이때 각 명령을 어디에서 구분해야 하는지를 쉘이 알 수 있도록 각 명령의 끝에 세미콜론을 두어야 한다.
$ function doubleit { read -p "Enter value: " value; echo $[ $value * 2 ]; }
$ doubleit
Enter value: 20
40
두 번째 방법은 여러 줄에 걸쳐서 함수를 정의하는 것이다. 이 방법에서 bash쉘은 더 많은 명령을 요구하기 위해 보조 프롬프트를 사용한다. 이때 각 명령의 마지막에 세미콜론을 둘 필요는 없어지고 단순히
$ function doubleit {
> read -p "Enter value: " value
> echo $[ $value * 2 ]
> }
$ doblelit
Enter value: 20
40
.bashrc 파일에서 함수 정의하기
커맨드라인에서 직접 쉘 함수를 정의하는 방법의 커다란 단점은 쉘을 종료할 때 함수도 사라진다는 것이다. 더 간단한 방법은 쉘이 새로운 쉘을 시작할 때마다 불러들이는 파일에 함수를 정의하는 것이다.
이를 위한 가장 좋은 장소는 .bashrc 파일이다. bash 쉘은 대화형이든 기존 쉘 안에서 새로운 쉘을 시작하든, 쉘이 새로 시작될 때마다 홈 디렉토리에서 이 파일을 찾는다.
이 방법을 잘 활용하면 우리가 정의한 라이브러리 혹은 다른 사람이 작성한 라이브러리 파일을 쉘을 시작할 때 마다 불러들일 수 있다. .bashrc 스크립트에 source 명령으로 존재하는 라이브러리 파일을 더해보자!!
# .bashrc
source {라이브러리 path}
📖출처
리처드 블룸, 크리스틴 브레스, ⌜리눅스 커맨드라인 쉘 스크립트 바이블⌟, 스포트라잇북(2016)
👍 개인 공부 기록용 블로그입니다. 오류나 조언이 있으시면 언제든지 댓글 혹은 메일로 남겨주시면 감사하겠습니다! 😄
댓글남기기