쉘 스크립트 - 2

  • 학습 개요
    쉘 스크립트에서 선택과 반복을 위한 제어 구조를 사용해보자.
    선택 구조인 if / case, 반복 주조인 for / while / until 명령의 문법과 의미를 알아 보자.
    조건 검사가 필요할 때 사용되는 명령과 수식의 작성법을 알아 보자.

  • 학습 목표

    1. 선택 구조를 사용하여 쉘 스크립트를 작성하자.
    2. 반복 구조를 사용하여 쉘 스크립트를 작성하자.
    3. 수식을 포함하는 쉘 명령을 선택과 반복 구조에서 사용하자.

선택 구조

제어 구조

  • 쉘 스크립트에서 실행을 제어하기 위해 선택과 반복 구조를 사용함.
  • if, for, case, while, until

if

  • 프로그래밍 언어에서 if 문의 기능

if command ...; then
  command ...
[ elif command; then
  command ... ]...
[ else
  command ... ]
fi
  • ;은 같은 라인에서 다른 단어(then elif else fi)와 구분이 필요할 때 사용함.
  • if다음의 명령을 실행하여 참이면 then 다음의 명령을 실행함. (if 명령은 종료됨)
    • if나 elif 다음에 조건 검사를 위한 test 명령을 사용할 수 있음.
    • if나 elif 다음에 나오는 마지막 명령의 종료 상탯값으로 참과 거짓을 구분함.
    • 종료 상탯값 0은 성공적 종료를 의미하며 참으로 간주.
  • 거짓이면 elif 다음의 명령을 실행하여 참 / 거짓을 판단하고 실행함.
  • 만족 되는 것이 없으면 else 다음의 명령을 실행함.
  [ec2-user@ip-AWS ~]$ cd /usr/bin
  [ec2-user@ip-AWS bin]$ echo $?
  0
  [ec2-user@ip-AWS bin]$ cd /bin/usr
  -bash: cd: /bin/usr: No such file or directory
  [ec2-user@ip-AWS bin]$ echo $?
  1
  [ec2-user@ip-AWS bin]$ if true; then
  > echo "SUCCESS"
  > else
  > echo "FAILURE"
  > fi
  SUCCESS
  [ec2-user@ip-AWS bin]$ if true; false; then
  > echo "TRUE"
  > fi

test

  • 조건 검사를 위해 사용하는 명령
  • 조건이 만족되면 종료 상탯값으로 0(true), 1(false)를 리턴함
  • test expression || [ expression ]
    • expression은 파일의 상태 검사, 문자열의 비교, 정수 비교를 위한 수식
    • **대괄호와 expression 사이에 공백이 있어야 함.
[ec2-user@ip-AWS ~]$ cat intCompare.sh
#! /bin/bash
if [ $# !=2 ]; then
        echo "you must supply two numbers as arguments"
        exit 1
fi

if [ $1 -eq $2 ]; then
        echo "$1 equals to $2"
elif [ $1 -gt $2 ]; then
        echo "$1 is greater than $2."
else
        echo "$1 is less than $2."
fi

echo "$1 + $2는 $[$1+$2]임."

[ec2-user@ip-AWS ~]$ chmod u+x intCompare.sh

[ec2-user@ip-AWS ~]$ ./intCompare.sh 36 68
./intCompare.sh: line 2: [: 2: unary operator expected
36 is less than 68.
36 + 68는 104임.

case

  • 다중 선택을 지원하는 복합 명령
    • switch 문과 비슷
case word in
  [ pattern [ | pattern ]... ) command...;; ]...
esac
  • word 부분을 먼저 확장하고 pattern과 매칭되는지 검사함
  • 매칭이 이루어지면 상응하는 명령이 수행됨
  • 일단 매칭이 이루어지면 이후의 매칭 시도는 없음
  • pattern에서 *은 프로그래밍에서 'default 키워드'를 사용함.

case에서 패턴 사용 예

pattern ) desc (word가 다음과 같은 경우 패턴 매칭이 일어남)
a) a인 경우
[[:alpha:]]) 1개의 알파벳 문자인 경우
???) 임의의 세 글자인 경우
*.txt .txt로 끝나는 경우
[aeiou]) 모음에 해당하는 영문 소문자 1개인 경우
[ABE][0-9] 앞 글자가 A, B, E중 하나이고 다음 글자가 숫자인 두 글자인 경우
*) 임의 길이의 글자와 매칭됨. case 명령에서 마지막 패턴으로 사용하는 것이 좋음

case 실행의 예

[ec2-user@ip-AWS ~]$ cat caseTest.sh
#!/bin/bash

echo "
plz select :
a. Display System Information
b. Show Information about File Systems
c. Summarlize Disk Usage Information
q. Quit
"

read -p "Enter selection [a, b, c or q] > "

case $REPLY in
  a|A)
      echo "Hostname : $HOSTNAME"
      uptime
      ;;
  b|B)
      df -h
      ;;
  c|C)
      if [$( id -u) -eq 0 ]; then
        echo "All user's home disk space utillization"
        du -sh /home/*
      else
        echo "($USER)' home disk space utilization"
        du -sh $HOME
      fi
      ;;
  q|Q)
      echo "Program terminated."
      exit
      ;;
  *)
      echo "Invalid entry" > $2
      exit 1
      ;;
esac

[ec2-user@ip-AWS ~]$ ./caseTest.sh
plz select :
a. Display System Information
b. Show Information about File Systems
c. Summarlize Disk Usage Information
q. Quit

Enter selection [a, b, c or q] > a
Hostname : ip-AWS.ap-northeast-2.compute.internal
07:45:43 up 34 days, 0 min,  1 user,  load average: 0.00, 0.00, 0.00


[ec2-user@ip-AWS ~]$ ./caseTest.sh
plz select :
a. Display System Information
b. Show Information about File Systems
c. Summarlize Disk Usage Information
q. Quit

Enter selection [a, b, c or q] > b
Filesystem      Size  Used Avail Use% Mounted on
devtmpfs        474M     0  474M   0% /dev
tmpfs           492M     0  492M   0% /dev/shm
tmpfs           492M  408K  492M   1% /run
tmpfs           492M     0  492M   0% /sys/fs/cgroup
/dev/xvda1      8.0G  1.9G  6.2G  24% /
tmpfs            99M     0   99M   0% /run/user/1000

[ec2-user@ip-AWS ~]$ ./caseTest.sh
plz select :
a. Display System Information
b. Show Information about File Systems
c. Summarlize Disk Usage Information
q. Quit

Enter selection [a, b, c or q] > c
./caseTest.sh: line 19: [1000: command not found
(ec2-user) home disk space utilization
92K     /home/ec2-user

[ec2-user@ip-AWS ~]$ ./caseTest.sh
plz select :
a. Display System Information
b. Show Information about File Systems
c. Summarlize Disk Usage Information
q. Quit

Enter selection [a, b, c or q] > d
./caseTest.sh: line 30: $2: ambiguous redirect

[ec2-user@ip-AWS ~]$ ./caseTest.sh
plz select :
a. Display System Information
b. Show Information about File Systems
c. Summarlize Disk Usage Information
q. Quit

Enter selection [a, b, c or q] > g
./caseTest.sh: line 30: $2: ambiguous redirect

[ec2-user@ip-AWS ~]$ ./caseTest.sh
plz select :
a. Display System Information
b. Show Information about File Systems
c. Summarlize Disk Usage Information
q. Quit

Enter selection [a, b, c or q] > q
Program terminated.

반복 구조

for

  • 모든 데이터를 한 차례씩 처리하는 제어구조
  •   for variable [ in word ... ]; do
        command ...
      done
  • word ... 부분 (값의 목록)을 먼저 확장함
  • word 목록에 존재하는 값을 순차적으로 변수 variable에 대입하고 do와 done 사이의 명령을 수행함.
  • word 부분이 없다면 in "$@"가 있는 것으로 가정함.
  [ec2-user@ip-AWS ~]$ echo {A..D}
  A B C D
  [ec2-user@ip-AWS ~]$ for i in {A..D}; do echo $i; done
  A
  B
  C
  D
  [ec2-user@ip-AWS ~]$ cat testFor.sh
  #! /bin/bash
  for FILE
  do
    echo $FILE
  done

  [ec2-user@ip-AWS ~]$ chmod u+x testFor.sh

  [ec2-user@ip-AWS ~]$ ./testFor.sh `ls`
  arg.sh
  caseTest.sh
  first.sh
  intCompare.sh
  list.bak
  testFor.sh
  whoson.sh
  • C나 Java에서 사용하는 형태

  •   for (( exp1; exp2; exp3 )); do
        command...
      done
  • exp1~3은 수식으로 각각 생략 가능

  • exp1은 제어 변수의 초기화를 위해 한 번 수행 됨

  • exp2가 참인 동안 명령과 exp3이 반복 수행 됨

  • [ec2-user@ip-AWS ~]$ cat testFor3.sh
      #! /bin/bash
      LIMIT=10
    
      for(( a=0; a<LIMIT; a++)); do
        echo "$a"
      done
      [ec2-user@ip-AWS ~]$ . testFor3.sh
      0
      1
      2
      3
      4
      5
      6
      7
      8
      9
      [ec2-user@ip-AWS ~]$

while

  • 조건이 참인 동안 명령을 반복함.
  •   while command...; do
        command
      done
  • while 다음에 나오는 명령을 실행하여 참 또는 거짓을 판단함
  • if 명령과 마찬가지로 종료 상탯값이 0이면 참으로 판단
  • 조건 비교를 위해 test expression 또는 [ expression ]을 자주 사용함.
  [ec2-user@ip-AWS ~]$ cat testWhile.sh
  #! /bin/bash
  N=1
  S=0

  while [ $N -le 10 ]; do
    echo -n "$N "
    S=$[ $S+$N ]
    N=$[ $N+1 ]
  done
  echo
  echo $S
  [ec2-user@ip-AWS ~]$ . testWhile.sh
  1 2 3 4 5 6 7 8 9 10
  55

for 와 while

  • for 명령 (2)를 다음과 같이 변환 가능
  •   (( exp1 ))
      while (( exp2 )); do
        command...
        (( exp3 ))
      done
  • (( expression ))은 수식 계산에 사용되는 복합 명령
  • let "expression"과 동일하며 test 명령 대신에 사용 가능
    • 조건 비교를 위해 test expression 또는 [ expression ]과 함께 자주 사용함.
  • while 다음의 (( expression ))에서 수식 결과가 0이 아닌 경우 종료 상탯값이 0이 되며 참으로 판단.
  [ec2-user@ip-AWS ~]$ cat testWhile2.sh
  #! /bin/bash
  LIMIT=10

  ((a=0))
  while (( a<LIMIT )); do
    echo "$a"
    (( a++ ))
  done
  [ec2-user@ip-AWS ~]$ . testWhile2.sh
  0
  1
  2
  3
  4
  5
  6
  7
  8
  9

until

  • 조건이 만족될 때까지(거짓인 동안) 명령을 반복하여 수행함
  •   until command ... ; do
        command ...
      done
  • until 다음에 나오는 명령이 참이 될 때까지 반복함
    • 거짓인 동안 반복하게 됨
  • 조건을 표시하기 위해 test expression, [ expression ], (( expression ))을 사용할 수 있음.
  [ec2-user@ip-AWS ~]$ cat testUntil.sh
  #! /bin/bash
  N=1
  S=0
  until [ $N -gt 10 ]; do
    echo -n "$N "
    let S=$S+$N
    let N=$N+1
  done
  echo
  echo $S
  [ec2-user@ip-AWS ~]$ . testUntil.sh
  1 2 3 4 5 6 7 8 9 10
  55
728x90
반응형

'OS > Linux' 카테고리의 다른 글

[Linux] 원격 관리  (0) 2020.12.13
[Linnux] 네트워크 설정 및 점검  (0) 2020.12.05
[Linux] 소프트웨어 관리  (0) 2020.11.01
[Linux] 프로세스 관리  (0) 2020.11.01
[Linux] 파일 시스템 관리  (0) 2020.10.25

쉘 스크립트 - 1

  • 학습 개요
    쉘은 명령어 해석기 이며 스크립트 언어이다.
    일련의 쉘 명령이나 함수의 조합을 프로그램의 제어 구조를 사용하여 쉘 스크립트 파일로 작성해 두면 편리하게 사용할 때가 있다.
    쉘 스크립트의 기본 작성법을 알아보고 변수와 함수의 사용법과 예제를 보자.

  • 학습 목표

    1. 쉘 스크립트 파일의 실행 방법을 알 수 있다.
    2. 쉘 스크립트에서 변수를 사용할 수 있다.
    3. 쉘 스크립트에서 함수를 정의하고 호출하여 사용할 수 있다.

쉘 스크립트 개요

쉘 스크립트

  • 쉘 명령어의 집합으로 이루어진 실행 가능한 텍스트 파일.
    • 쉘이 파일의 내용을 읽어 처리함.
    • 선택 / 반복 등의 프로그래밍 구조를 사용할 수 있음.
    • 긴 작업, 반복적으로 일어나는 작업을 쉘 스크립트로 작성할 수 있음.
    • 쉘 스크립트를 새로운 명령어처럼 사용할 수 있음.
  • 예)
    • ~/.bash_profile, ~/.bachrc 등의 쉘 초기화 스크립트.
    • 디렉토리 /etc/rc.d/init.d/에 존재하는 시스템 초기화 스크립트.
  • 3차 USE_SHELL을 복습 할 것.

쉘 스크립트의 실행 방법

  • bash script_file
    • 스크립트 파일에 실행 권한을 추가할 필요가 없음.
    • 명령 행에서 script_file 다음에 인수를 추가할 수 있음.
    • 서브 쉘을 새로 생성하여 스크립트를 실행함.
  • ./script_file
    • 스크립트 파일에 실행 권한을 추가 해야 함.
    • PATH 환경 변수에 설정된 디렉토리에서 스크립트 파일을 찾음.
    • 스크립트 파일의 첫 행에서 #! 다음에 해석기(/bin/bash)를 지정함.
    • 서브 쉘을 새로 생성하여 스크립트를 실행함.
  • source script_file || / . script_file
    • source는 쉘 내장 명령이며 현재 쉘에서 스크립트 파일을 실행함.

쉘 스크립트 문법

  • #으로 시작하는 단어와 행은 주석으로 처리 됨.
  • $0은 스크립트 파일의 이름으로 확장됨.
    • source 명령으로 실행하는 경우 쉘의 이름(bash)으로 확장 됨.
  • $1은 첫 번째 인수, $2는 두 번째 인수로 확장 됨
  • 스크립트가 복잡하다면 적절한 echo 명령을 넣는 것이 좋음.
  • 변수=값을 사용하여 변수에 값을 지정하고 $변수를 사용하여 값을 추출할 수 있음
    • 등호(=)의 좌우에 공백이 있으면 안됨
  • bash -x script_file과 같이 실행하면 수행되는 명령을 확인할 수 있음.(디버깅 모드)

변수의 사용

쉘스크립트에서 변수의 사용

  • 선언 없이 변수를 사용할 수 있음
    • MYCOLOR=blue || echo $PATH
  • 변수의 값은 기본적으로 문자열로 취급
    • 연산이 필요하고, 변환이 가능한 경우에 정수로 다루어짐
  • 변수 이름의 작명
    • 대소문자 구분
    • 영문자, 숫자, 언더스코어로 구성
    • 첫 자는 숫자가 될 수 없음.

변수 사용의 예

ex desc
a=ls 변수 a에 문자열 'ls'를 대입
b="A string" 따옴표를 사용하여 공백을 가진 문자열을 대입
c="A string and $b" $b를 '변수 확장'한 후 문자열을 대입
d=$(ls wc -l)
e=$[5*7] $[...]는 '수식 확장'을 의미. 대괄호 안의 수식을 계산한 후 결과를 대입
f="\t\tA string\n" 이스케이프 문자 \를 사용
g=5 h="A String" 한 행에 2개의 변수를 사용하는 예
i=${b}1 변수 이름을 중괄호로 묶으면 뒤따라 나오는 문자를 분리할 수 있음. "A string1"이 대입됨. 실제 $b는 ${b}를 줄여 쓴 형태
$a 먼저 변수 확장이 일어나고, 쉘은 이것을 하나의 명령어로 해석하여 처리
$a=$e 변수 확장의 결과는 ls=35. 쉘은 이 자체를 하나의 명령어로 처리하므로 오류가 발생. eval "$a=$e"를 실행할 수 있음

명령 행 인수

  • 쉘이 스크립트를 처리할 때 사용되는 인수
    • 사용자가 스크립트 실행에 필요한 입력값을 주어야 함
  • $0은 스크팁트 파일의 이름으로 확장
  • 나머지를 위치 매개변수(positional parameteer)라 하며 $1, $2, $3 등은 이러한 인수를 의미함
  [ec2-user@ip-aws ~]$ cat > arg.sh
  echo "This script's name is $0"
  echo Argument 1 : $1
  echo Argument 2 : $2
  ^C
  [ec2-user@ip-aws ~]$ ls
  arg.sh  first.sh  list.bak
  [ec2-user@ip-aws ~]$ chmod u+x arg.sh
  [ec2-user@ip-aws ~]$ ./arg.sh first second
  This script's name is ./arg.sh
  Argument 1 : first
  Argument 2 : second
  [ec2-user@ip-aws ~]$ /home/ec2-user/arg.sh one two
  This script's name is /home/ec2-user/arg.sh
  Argument 1 : one
  Argument 2 : two

특별한 매개변수

  • 명령 행 인수와 관계가 있는 특별한 변수
  • 변수의 값을 참조만 할 수 있음
ex desc
$* "$*"는 $0을 제외한 모든 위치 매개변수를 포함하는 1 개의 큰 따옴표 like "$1 $2 $3 ..."
$@ 여러 개별 큰 따옴표 문리된 문자열로 확장 됨. "$1", "$2", "$3", ...
$$ 쉘의 프로세스 ID PID로 확장
$# 위치 매개변수의 개수로 확장
$? 최근에 실행된 포어그라운드 명령의 종료 상탯값으로 확장됨. 성공적 종료는 0.
$! 최근 실행된 백그라운드 명령의 프로세스 ID로 확장됨.

read

  • 키보드로 부터 한 라인을 읽은 후, 단어를 상응하는 변수에 저장함.
    • 대화식으로 스크립트를 실행시킬 수 있음.
  • read [options] [variable...]
    • 첫 번째 변수에 첫 번째 단어를, 두 번째 변수에 두 번째 단어를 저장.
    • 마지막 면수에 나머지 모두를 저장.
    • 남아있는 변수가 있으면 빈 문자열이 됨.
    • 변수의 이름을 사용하지 않으면 쉘 면수 REPLY에 저장됨.
    • 옵션 -p prompt는 입력을 위한 프롬프트를 지정함.

함수의 사용

함수

  • 함수는 쉘 스크립트에서 반복적으로 사용되는 명령의 묶음.
  • 쉘 스크립트 파일에 함수를 정의할 수 있음.
    • 정의되어 있는 함수를 호출하여 사용함.

함수의 호출 방법

  • 함수가 정의된 스크립트 파일에서 함수를 호출하여 사용할 수 있음.
  • 함수가 정의된 스크립트 파일을 실행하면 쉘 환경에 함수 정의가 추가됨.
    -> 같은 쉘에서 함수 이름을 쉘 명령어처럼 사용.
    • source 명령이나 도트(.) 명령으로 쉘 스크립트를 실행하면 함수 정의가 현재 쉘 환경에 추가됨.
      • set 명령으로 확인하고 unset name으로 삭제할 수 있음.
    • 이후 함수를 쉘 명령어처럼 사용할 수 있음.

함수 정의 방법

  function name {
    command ...
    return
  }

  name() {
    command ...
    return
  }
  • return [n] 문은 함수를 종료하는 문장으로 종료 상탯값을 리턴할 수 있음(n이 생량되면 직전 명령의 종료 상탯값을 리턴)
  • 함수 정의를 항상 사용하려면 .bashrc에 넣는것이 좋음
    • alias 설정도 마찬가지.

함수 실행 예

  [ec2-user@ip-aws ~]$ touch whoson.sh
  [ec2-user@ip-aws ~]$ vi whoson.sh
  [ec2-user@ip-aws ~]$ cat whoson.sh
  #!/bin/bash

  whoson () {
    date
    user=$USER
    echo "$user currently logged on"
  }

  echo "STEP 1"
  whoson
  echo "STEP 3"

  [ec2-user@ip-aws ~]$ . whoson.sh
  STEP 1
  Thu Nov  5 12:50:41 UTC 2020
  ec2-user currently logged on
  STEP 3

  [ec2-user@ip-aws ~]$

  [ec2-user@ip-aws ~]$ . whoson.sh
  STEP 1
  Thu Nov  5 12:50:59 UTC 2020
  ec2-user currently logged on
  STEP 3

  [ec2-user@ip-aws ~]$ whoson
  Thu Nov  5 12:51:19 UTC 2020
  ec2-user currently logged on

  [ec2-user@ip-aws ~]$ echo $user
  ec2-user
[ec2-user@ip-aws ~]$ cat .bashrc
# .bashrc

# Source global definitions
if [ -f /etc/bashrc ]; then
  . /etc/bashrc
fi

# Uncomment the following line if you don't like systemctl's auto-paging feature:
# export SYSTEMD_PAGER=

# User specific aliases and functions

[ec2-user@ip-aws ~]$ vi ~/.bashrc

[ec2-user@ip-aws ~]$ cat .bashrc
# .bashrc

# Source global definitions
if [ -f /etc/bashrc ]; then
  . /etc/bashrc
fi

# Uncomment the following line if you don't like systemctl's auto-paging feature:
# export SYSTEMD_PAGER=

# User specific aliases and functions
arg1 () {
  echo "$1"
}

ds() {
  echo "DISK DPACE UTILIZATION FOR $USER"
  du -sh ~
}

[ec2-user@ip-aws ~]$ . ~/.bashrc

[ec2-user@ip-aws ~]$ arg1 first
first

[ec2-user@ip-aws ~]$ ds
DISK DPACE UTILIZATION FOR ec2-user
80K     /home/ec2-user
728x90
반응형

+ Recent posts