본문 바로가기

운영체제/리눅스(Linux)

쉘 프로그래밍(Shell Programming)

파일 포맷

- 파일 첫머리의 #!은 shebang 으로 부르는 것으로 스크립트를 실행하기 위한 인터프리터(여기서는 bash) 이름을 시스템에게 알려준다.

#!/bin/bash
echo "Hello World"

 

실행 시

- 스크립트 실행 시에 아래와 같이 경로를 포함해야 한다.

- 경로를 포함하지 않으면 (예를 들어 $ hello_world) 시스템은 환경변수 PATH에 규정된 디렉토리 목록에 있는 실행프로그램을 검색하게 된다.

$ ./hello_world

 

※ 스크립트 저장 장소

~/bin 디렉토리에는 개인적인 용도로 사용하려는 스크립트를 주로 저장하도록 한다.

(이를 위해서는 먼저 .bashrc에 ~/bin 디렉토리를 PATH 변수에 자동으로 추가하게끔 해야 한다)

($ export PATH=~/bin:"$PATH" 명령어로 추가하도록 하자)

시스템 관리자용 스크립트는 /usr/local/sbin 디렉토리에 저장한다. 

 

※ 상수와 변수

쉘 스크립트는 상수와 변수를 구분하지 않는다. 다만, 일반적으로 상수는 대문자로, 변수는 소문자로 기입한다.

 

 

변수

- 타입은 무관하다.

- 하지만, 다른 프로그래밍 언어와 달리 쉘은 변수에 할당되는 값을 모두 문자열로 인식한다.

VAR=value

ex)
MY_MESSAGE="Hello World"
MY_SHORT_MESSAGE=hi
MY_NUMBER=1
MY_PI=3.142
MY_OTHER_PI="3.142"
MY_MIXED=123abc

 

함수

- 함수는 return 명령어 등 최소한 하나의 명령어를 포함해야 한다.

- 아래의 두가지 형식이 가능하다.

- 방식은 $(name) 이다

function name {
	commands
    return
}

name() {
	commands
    return
}

 

※ 지역 변수, 전역 변수

- 쉘 함수 안의 지역 변수는 전역 변수에 영향을 받지 않는다.

 

 

중간 결과

- (예시) html 파일을 생성하는 쉘 스크립트

코드)

더보기
#!/bin/bash

# Program to output a system information page
TITLE="System Information Report For $HOSTNAME"
CURRENT_TIME=$(date +"%x %r %Z")
TIME_STAMP="Generated $CURRENT_TIME, by $USER"

report_uptime() {
    cat <<- _EOF_
            <H2> System Uptime </H2>
            <PRE> $(uptime) </PRE>
_EOF_
    return
}

report_disk_space() {
cat <<- _EOF_
            <H2> Dist Space Utilization </H2>
            <PRE> $(df -h) </PRE>
_EOF_
    return
}

report_home_space() {
    if [[ $(id -u) -eq 0 ]]; then  # 아래에 나올 조건문을 활용한 것으로, 슈퍼유저(uid 0) 인 경우와 아닌 경우를 구분한다.
    cat <<- _EOF_
            <H2> Home Space Utilization </H2>
            <PRE> $(du -sh /home/*) </PRE>
_EOF_
    else
    cat <<- _EOF_
            <H2> Home Space Utilization </H2>
            <PRE> $(du -sh $HOME) </PRE>
_EOF_
    fi
    return
}

}

cat << _EOF_
<HTML>
          <HEAD>
              <TITLE> $TITLE </TITLE>
          </HEAD>
          <BODY>
              <H1> $TITLE </H1>
              <P> $TIME_STAMP <\P>
              $(report_uptime)
              $(report_disk_space)
              $(report_home_space)
          </BODY>
</HTML>
_EOF_

결과)

더보기
<HTML>
          <HEAD>
              <TITLE> System Information Report For donghoon-System-Product-Name </TITLE>
          </HEAD>
          <BODY>
              <H1> System Information Report For donghoon-System-Product-Name </H1>
              <P> Generated 2022년 01월 14일 오후 03시 34분 19초 KST, by donghoon <\P>
                          <H2> System Uptime </H2>
            <PRE>  15:34:19 up  4:35,  1 user,  load average: 0.26, 0.23, 0.10 </PRE>
                          <H2> Dist Space Utilization </H2>
            <PRE> Filesystem      Size  Used Avail Use% Mounted on
udev            7.8G     0  7.8G   0% /dev
tmpfs           1.6G  2.1M  1.6G   1% /run
/dev/sdc2       234G  9.8G  212G   5% /
tmpfs           7.8G   48M  7.8G   1% /dev/shm
tmpfs           5.0M  4.0K  5.0M   1% /run/lock
tmpfs           7.8G     0  7.8G   0% /sys/fs/cgroup
/dev/loop1       44M   44M     0 100% /snap/snapd/14295
/dev/loop2      2.3M  2.3M     0 100% /snap/gnome-system-monitor/148
/dev/loop3       56M   56M     0 100% /snap/core18/2253
/dev/loop5      640K  640K     0 100% /snap/gnome-logs/106
/dev/loop6      219M  219M     0 100% /snap/gnome-3-34-1804/77
/dev/loop7       62M   62M     0 100% /snap/core20/1270
/dev/loop8       66M   66M     0 100% /snap/gtk-common-themes/1519
/dev/loop0      384K  384K     0 100% /snap/gnome-characters/550
/dev/loop9      2.5M  2.5M     0 100% /snap/gnome-calculator/748
/dev/loop11     2.7M  2.7M     0 100% /snap/gnome-system-monitor/174
/dev/sdc1       511M  6.6M  505M   2% /boot/efi
/dev/loop10     256M  256M     0 100% /snap/gnome-3-34-1804/36
/dev/loop12      30M   30M     0 100% /snap/snapd/8542
/dev/loop13     768K  768K     0 100% /snap/gnome-characters/741
/dev/loop14     248M  248M     0 100% /snap/gnome-3-38-2004/87
/dev/loop15     1.0M  1.0M     0 100% /snap/gnome-logs/100
/dev/loop16     2.5M  2.5M     0 100% /snap/gnome-calculator/884
/dev/loop17      63M   63M     0 100% /snap/gtk-common-themes/1506
/dev/loop18     128K  128K     0 100% /snap/bare/5
tmpfs           1.6G   28K  1.6G   1% /run/user/121
tmpfs           1.6G   52K  1.6G   1% /run/user/1000
/dev/sdd1       932G  887G   45G  96% /media/donghoon/Samsung_T3
/dev/loop19      56M   56M     0 100% /snap/core18/2284 </PRE>
                          <H2> Home Space Utilization </H2>
            <PRE> 681M  /home/donghoon </PRE>
          </BODY>
</HTML>

 

※ 참고

df -h 명령으로 디스크 사용 공간을 확인한다.

du -sh 명령으로 사용자 공간을 확인한다.

 

 

조건문

- '[' 와 'expression' 사이는 한칸 띄워야 한다. ']' 도 마찬가지.

if [ expression; ] then
	commands
elif [ expression; ] then
	commands
else
	commands
fi

 

파일 표현식

 

문자열 표현식

 

정수 표현식

 

정수 표현식 + 정규 표현식 사용 예시)

- [[ ]]는 현대식 테스트 방법으로 자세한건 참조 링크의 p389 ~ 390을 참고하도록 한다.

- 정규 표현식과 매칭은 [[ expression =~ regex ]] 이다. ( == 가 아님에 주의

더보기
#!/bin/bash
# test-integer: evaluate the value of an integer.

INT=st

if [ -z "$INT" ]; then
    echo "INT is empty." >&2
    exit 1
fi

if [[ "$INT" =~ ^-?[0-9]+$ ]]; then
    if [ $INT -eq 0 ]; then
        echo "INT is zero."
    else
        if [ $INT -lt 0 ]; then
            echo "INT is negative."
        else
            echo "INT is positive."
        fi

        if [ $((INT % 2)) -eq 0 ]; then
            echo "INT is even."
        else
            echo "INT is odd."
        fi
    fi
else
    echo "INT is not an interger." >&2
    exit1
fi

 

 

※ 명령어는 종료 될때 종료 상태(exit status) 값을 생성한다.

※ 생소한 명령어 모음

명령어 사용 예시 설명
$! echo $! 백그라운드에서 가장 마지막에 실행된 프로세스 명령어의 PID 값 출력
$? echo $? 가장 마지막에 종료된 프로세스(명령어)의 종료 상태
(정상 0, 이외에는 조건에 따라 다른 return) 출력
$$ echo $$ 사용하고 있는 Shell의 PID값을 출력한다. 현재 bash 쉘의 프로세스 ID

 

 

제어 연산자

- command1 && command2 : 두개 명령어가 모두 실행되면,  command1이 성공했다는 것을 의미한다.

- command1 || command2 : 두개 명령어가 모두 실행되면, command1이 실패했다는 것을 의미한다.

mkdir temp && cd temp # temp 디렉토리가 생성되면(성공), temp 디렉토리로 작업 디렉토리를 이동한다.

[ -d temp ] || mkdir temp # temp 디렉토리가 존재하지 않으면(실패), temp 디렉토리를 만든다.

 

 

사용자 입 출력

-  read 명령어로 사용자 입력을 받는다.

- 예시) 사용자의 비번을 입력 받아 출력하는 프로그램. 시간 제한 10초를 두었다.

#!/bin/bash

if read -t 10 -sp "Enter secret passphase > " secret_pass; then
    echo -e "\nsecret passphase = $secret_pass"
else
    echo -e "\nInput timed out" >&2
    exit 1
fi

 

입력 필드 구분

- IFS(입력 필드 구분자)를 두어 ' '(스테이스), '\t'(탭), '\n'(개행문자) 외에도 설정할 수 있다.

- 파이썬으로 치면 .split()의 역할을 한다. 

- 예시) 사용자 이름을 입력 받아 정보를 출력

#!/bin/bash
FILE=/etc/passwd

read -p "Enter a username > " user_name

file_info=$(grep "^$user_name:" $FILE)

if [ -n "$file_info" ]; then
    IFS=":" read user pw uid gid name home shell <<< "$file_info"
    echo "User =     $user"
    echo "UID =     $uid"
    echo "GID =     $gid"
    echo "Full Name =     $name"
    echo "Home Dir. =     $home"
    echo "Shell =     $shell"
else
    echo "No such user '$user_name'" >&2
    exit 1
fi

 

 

출처 : https://wiki.lib.sun.ac.za/images/c/ca/TLCL-13.07.pdf

 

 

 

반응형

'운영체제 > 리눅스(Linux)' 카테고리의 다른 글

tee 명령어  (0) 2022.09.06
리눅스 소소한 질문 모음  (0) 2022.01.11
Makefile 정리  (0) 2021.10.25