카테고리 없음

The linux command line 26장: Shell script (top-down design)

seul chan 2021. 5. 2. 21:38

26. Top-down design

프로그램이 점점 커지고 복잡해지면, 디자인하고 유지보수하기가 점점더 어려워짐.

top-down design: 상위의 단계부터 정의하고 디테일한 단계로 내려오는 방식을 얘기함

  • 크고 복잡한 작업을 작고 간단한 작업으로 쪼갤 수 있음
  • 쉘스크립트를 포함한 많은 프로그램을 디자인할 때 쓰이는 방법

Shell functions

이전 블로그 포스트에서 만들었던 report program은 다음 단계로 쪼갤 수 있따.

  1. Open page.
  2. Open page header.
  3. Set page title.
  4. Close page header.
  5. Open page body.
  6. Output page heading.
  7. Output timestamp.
  8. Close page body.
  9. 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
}