26. Top-down design
프로그램이 점점 커지고 복잡해지면, 디자인하고 유지보수하기가 점점더 어려워짐.
top-down design: 상위의 단계부터 정의하고 디테일한 단계로 내려오는 방식을 얘기함
- 크고 복잡한 작업을 작고 간단한 작업으로 쪼갤 수 있음
- 쉘스크립트를 포함한 많은 프로그램을 디자인할 때 쓰이는 방법
Shell functions
이전 블로그 포스트에서 만들었던 report program은 다음 단계로 쪼갤 수 있따.
- Open page.
- Open page header.
- Set page title.
- Close page header.
- Open page body.
- Output page heading.
- Output timestamp.
- Close page body.
- Close page
다음 부분에서는 7-8 단계에 내용을 추가할텐데, 다음과 같은 내용을 추가해보자.
- system uptime and load
- disk space
- home space
#!/bin/bash
# Program to output a system information page
TITLE="System Information Report For $HOSTNAME"
CURRENT_TIME="$(date +"%x %r %Z")"
TIMESTAMP="Generated $CURRENT_TIME, by $USER"
cat << _EOF_
<html>
<head>
<title>$TITLE</title>
</head>
<body>
<h1>$TITLE</h1>
<p>$TIMESTAMP</p>
$(report_uptime)
$(report_disk_space)
$(report_home_space)
</body>
</html>
_EOF_
위의 코드에서 볼 수 있듯이 명령어를 넣어주고 두가지 방법으로 함수를 작성할 수 있다.
- 분리된 script를 만들고
PATH
디렉토리에 추가하덙, shell function
이라는 방식으로 프로그램 안에 스크립트를 embed 할 수 있다.
# formal form
function name {
commands
return
}
# simpler form
name () {
commands
return
}
간단한 shell function을 작성해보자.
#!/bin/bash
# shell function demo
function step2 {
echo "Step 2"
return
}
# main program starts here
echo "Step 1"
step2
echo "Step 3"
$ ./shell_function_example
Step 1
Step 2
Step 3
Local variables
지금까지는 global variable만 사용되었는데,
다른 많은 프로그래밍 언어들처럼 shell script도 함수에서 local variable이 사용된다.
#!/bin/bash
# local-vars: script to demonstrate local variables
foo=0 # global variable
func_1 () {
local foo
foo=1
echo "func_1: foo = $foo"
}
func_2() {
local foo
foo=2
echo "func_2: foo = $foo"
}
echo "global: foo = $foo"
func_1
echo "global: foo = $foo"
func_2
echo "global: foo = $foo"
실제로 실행하면 예상했던대로 동작하는걸 볼 수 있다
$ local_variable_example
global: foo = 0
func_1: foo = 1
global: foo = 0
func_2: foo = 2
global: foo = 0
keep scripts running
이제 실제로 세 함수를 작성해보자.
#!/bin/bash
# Program to output a system information page
report_uptime() {
cat <<- _EOF_
<h2>System Uptime</h2>
<pre>$(uptime)</pre>
_EOF_
return
}
report_disk_space () {
cat <<- _EOF_
<h2>Disk Space Utilization</h2>
<pre>$(df -h)</pre>
_EOF_
return
}
report_home_space () {
cat <<- _EOF_
<h2>Home Space Utilization</h2>
<pre>$(du -sh /home/*)</pre>
_EOF_
return
}
TITLE="System Information Report For $HOSTNAME"
CURRENT_TIME="$(date +"%x %r %Z")"
TIMESTAMP="Generated $CURRENT_TIME, by $USER"
cat << _EOF_
<html>
<head>
<title>$TITLE</title>
</head>
<body>
<h1>$TITLE</h1>
<p>$TIMESTAMP</p>
$(report_uptime)
$(report_disk_space)
$(report_home_space)
</body>
</html>
_EOF_
shell function은 ~/.bashrc
파일 등에서도 사용될 수 있다.
이는 alias 대신에 조금 복잡하거나 더 verbose한 경우 유용하게 사용할 수 있다.
ds () {
echo "Disk Space Utilization forr $HOSTNAME"
df -h
}