Vorsprung durch Technik

블로그 이미지

MSNU

BASH SHELL 배쉬 셀

myPPT 2015. 7. 2. 21:41





































































Bash 셸

7.1 Bash 쉘 소개



Bash(Borune-again shell)

 리눅스, 맥 OS X 등의 운영 체제의 기본 쉘

 Bash 문법은 본 쉘의 문법을 대부분 수용하면서 확장

 시작 파일(start-up file)

 /etc/profile 

전체 사용자에게 적용되는 환경 설정, 시작 프로그램 지정

 /etc/bashrc 

전체 사용자에게 적용되는 별명과 함수들을 정의 

 ~/.bash_profile 

각 사용자를 위한 환경을 설정, 시작 프로그램 지정 

 ~/.bashrc 

각 사용자를 위한 별명과 함수들을 정의 

Bash 시작 과정

시작 파일 예

# .bash_profile 

# 사용자의 환경변수 설정 및 시작 프로그램 

if [ -f ~/.bashrc ]

then 

. ~/.bashrc 

fi 


PATH=$PATH:$HOME/bin:.

BASH_ENV=$HOME/.bashrc 

export USERNAME BASH_ENV PATH 


# .bashrc 

# 사용자의 별명 설정 

alias rm='rm -i' 

alias cp='cp -i' 

alias mv='mv -i' 

alias ll='ls -al --color=yes' 

# 시스템 시작 파일 실행

if [ -f /etc/bashrc ]

then 

. /etc/bashrc 

fli


$ alias


7.2 별명 및 히스토리 기능




별명

 alias 명령어

 스트링이 나타내는 기존 명령에 대해 새로운 단어를 별명으로 정의 

$ alias 단어=스트링 

$ alias dir=ls -aF

$ dir


$ alias h=history

$ alias list=ls –l [--color=auto]


 현재까지 정의된 별명들을 확인

$ alias # 별명 리스트

dir ls -aF

h history

list ls –l


 이미 정의된 별명 해제

$ unalias 단어 


히스토리

 입력된 명령들을 기억하는 기능

$ history [개수]


 기억할 히스토리의 크기

$ echo $HISTSIZE

$ HISTSIZE=100

$ echo $HISTSIZE


 로그아웃 후에도 히스토리가 저장되도록 설정

$ echo $HISTFILESIZE

$ HISTFIESIZE=100

$ echo $HISTFILESIZE


재실행







 예

$ !! # 바로 전 명령 재실행

$ !999 # 999번 이벤트 재실행

$ !shift # shift로 시작하는 최근 명령 재실행

$ !?.bashrc # .bashrc를 포함하는 최근 명령 재실행


7.3 변수




단순 변수(simple variable)

 하나의 값(문자열)만을 저장할 수 있는 변수

$ 이름=단어 

$ city=incheon


 변수의 값 사용

$ echo $city

incheon


 변수에 어느 때나 필요하면 다른 값을 대입

$ city=seoul


 한 번에 여러 개의 변수를 생성

$ country=korea city=incheon


단순 변수

 한글 스트링을 값으로 사용

$ country=대한민국 city=인천

$ echo $country $city

대한민국 인천


 따옴표를 이용하면 여러 단어로 구성된 스트링을 저장

$ address=“인천시 연수구 송도동” 


리스트 변수(list variable)

 한 변수에 여러 개의 값(문자열)을 저장할 수 있는 변수 

$ 이름=( 단어리스트 )

$ cities=(서울 부산 인천)


 리스트 변수 사용


리스트 변수 사용 예

 리스트 변수 사용

$ echo ${cities[*]}

서울 부산 인천

$ echo ${cities[1]}

서울


 리스트의 크기

$ echo ${#cities[*]}     # 리스트 크기

3

$ echo ${cities[3]}


 리스트 변수에 새로운 도시 추가

$ cities=(${cities[*]} 제주)

$ echo ${cities[3]}

제주


표준입력 읽기

 read 명령어

 표준입력에서 한 줄을 읽어서 단어들을 변수들에 순서대로 저장

 남은 단어들은 마지막 변수에 모두 저장 

$ read 변수1, ..., 변수n

$ read x y

Merry Christmas !

$ echo $x

Merry

$ echo $y

Christmas !


 변수를 하나만 사용

$ read x 

Merry Christmas !

$ echo $x

Merry Christmas !


7.4 지역변수와 환경변수




환경변수와 지역변수

 쉘 변수

 환경변수와 지역변수 두 종류로 나눌 수 있다 

 환경 변수는 값이 자식 프로세스에게 상속되며 지역변수는 그렇지 않다


환경변수와 지역변수 예

$ country=대한민국 city=서울

$ export country

$ echo $country $city

대한민국 서울


$ sh

$ echo $country $city

대한민국

$ ^D


$ echo $country $city

대한민국 서울


사전 정의 환경변수(predefined environment variable)

 그 의미가 미리 정해진 환경변수들












$ echo 홈 = $HOME 사용자 = $USER 쉘 = $SHELL

홈 = /home/mysung 사용자 = mysung 쉘 = /bin/bash

$ echo 터미널 = $TERM 경로 리스트 = $PATH

터미널 = ansi 경로 리스트 = /bin:/usr/bin:/usr/local/bin

사전 정의 지역 변수(predefined local variable)

#!/bin/bash 

# builtin.bash

echo 이 스크립트 이름: $0 

echo 첫 번째 명령줄 인수: $1 

echo 모든 명령줄 인수: $* 

echo 명령줄 인수의 개수: $# 

echo 이 스크립트를 실행하는 프로세스 번호: $$

echo 이전 명령의 반환 값: $?


$ chmod +x builtin.bash

$ builtin.bash hello shell

이 스크립트 이름: builtin.sh

첫 번째 명령줄 인수: hello

모든 명령줄 인수: hello shell

이 스크립트를 실행하는 프로세스 번호: 12345

이전 명령의 반환 값: 0



7.5 Bash 쉘 스크립트 





Bash 스크립트 작성 및 실행 과정

(1) 에디터를 사용하여 Bash 스크립트 파일을 작성한다. 

#!/bin/bash 

# state.bash 

echo -n 현재 시간: 

date 

echo 현재 사용자: 

who

echo 시스템 현재 상황: 

uptime

(2) chmod를 이용하여 실행 모드로 변경한다. 

$ chmod +x state.bash  

(3) 스크립트 이름을 타이핑하여 실행한다.

$ state.bash  


if 문

 if 문

if 조건식 

then

   명령어리스트

fi


 조건식

test 식 

[ 식 ]    (반드시 빈칸)


 예

if `test $# -eq 1`

if [ $# -ne 1 ]


#!/bin/bash

# wc1.bash 파일명

# 명령줄 인수 개수를 확인하고 wc 명령어를 실행

if [ $# -ne 1 ]

then

   echo 사용법: $0 파일

   exit 1

fi

file=$1

wc $file


$ wc1.bash

사용법: wc1.bash 파일

$ wc1.bash wc1.bash

11  30 159 wc1.bash

if-then-else

 if-then-else 구문


if 조건식

then

명령어리스트

elif

명령어리스트

else

명령어리스트

fi


#!/bin/bash

# count1.bash [디렉터리] 

# 대상 디렉터리 내의 파일과 서브디렉터리 개수를 프린트

if [ $# -eq 0 ]

then

   dir="."

else

   dir=$1

fi

echo -n $dir 내의 파일과 서브디렉터리 개수:

ls $dir | wc -l


$ count1.bash 

. 내의 파일과 서브디렉터리 개수: 17

7.6 식





비교 연산

 산술 비교 연산









 문자열 비교 연산 


문자열 비교 연산자

#!/bin/bash

# reply.bash

# 계속 여부를 입력받아 프린트한다

echo -n "계속 하겠습니까 ? "

read reply

if [ $reply == "yes" ]

then

    echo 예

elif [ $reply == "no" ]

then

    echo 아니오

fi


$ reply.bash

계속 하겠습니까 ?아니오

아니오

#!/bin/bash

# reply2.bash

# 계속 여부를 입력받아 프린트한다

echo -n "계속 하겠습니까 ? "

read reply

case $reply in

y*)

    echo 예 ;;

n*)

    echo 아니오

esac


$ reply2.bash

계속 하겠습니까 ?아니오

아니오

파일 관련 연산

파일 관련 연산: 예

if [ -e $file ]

then # $file이 존재하면 

   wc $file

else # $file이 존재하지 않으면 

   echo "오류 ! 파일 없음“

fi 


if [ -d $dir ] 

then

   echo -n $dir 내의 파일과 서브디렉터리 개수:

   ls $dir | wc -l

else

   echo $dir\: 디렉터리 아님

fi 


부울 연산자

 조건식에 부울 연산자 사용

 ! 부정(negation)

 && 논리곱(logical and) 

 || 논리합(logical or) 


# $file이 일반 파일이고 쓸 수 있으면

if [ -f $file ] && [ -w $file ] 

then

   uptime > $file

fi



if [ ! -e $file ]

then # $file이 존재하지 않으면 

   echo $file : 파일 없음 

fi


if [ ! -d $file ]

then # $dir이 디렉터리가 아니면

   echo $file : 디렉터리 아님 

fi


산술 연산

• 본쉘의 산술 연산


$ a=2+3

$ echo $a

$ a=`expr 2 + 3` # 반드시 빈칸


• 콘쉘의 let 명령어를 이용한 산술 연산


$ let 변수=수식

$ let a=2*3

$ echo $a

6

$ let a=$a+2

$ echo $a

8

$ let a*=10

$ let b++

산술 연산자



변수 타입 선언

 변수 타입 선언: declare 


$ declare -i a # a는 정수형 변수

$ a=12

$ a=a+1 # let 필요 없음

$ echo $a

$ a=12.3 # 오류 메세지

bash: 12.3: syntax error in expression (error token is ".3")

$ declare -r b=23.4 # 읽기 전용 

$ b=23.5 # 오류 메세지

bash: b: readonly variable



7.7 제어구조




Bash 제어구조

 조건

if

 스위치

case

 반복 

for, while, until 


조건문


if 조건식 

then

   명령어리스트

fi


if 조건식 

then

   명령어리스트 

else

   명령어리스트

fi


 중첩 조건문 


if 조건식 

then

   명령어리스트 

elif 조건식

then

   명령어리스트 

else

   명령어리스트 

fi

중첩 조건문: 예

#!/bin/bash

# score1.bash 

# 점수에 따라 학점을 결정하여 프린트

echo -n '점수 입력: '

read score

if (( $score >= 90 ))

then

   echo A

elif (( $score >= 80 ))

then

   echo B

elif (( $score >= 70 ))

then

   echo C

else

   echo 노력 요함

fi


$score1.bash

점수 입력: 99

A


스위치

case 단어 in

   패턴1) 명령어리스트;;

   패턴2) 명령어리스트;;

   ...

   *) 명령어리스트;;

esac


#!/bin/bash

# 사용법: score2.bash 

# 점수에 따라 학점을 결정하여 프린트한다.

echo -n '점수 입력: '

read score

let grade=$score/10

case $grade in

   "10" | "9") echo A;;

   "8") echo B;;

   "7") echo C;;

   *) echo 노력 요함;;

esac


반복문: for

 for 구문

 리스트의 각 값에 대해서 명령어들을 반복


for 이름 [in 단어리스트]

do

   명령어리스트 

done


#!/bin/bash

# for.bash

for color in red yellow green blue

do

  echo one color is $color

done



#!/bin/bash

# invite.bash

# 저녁 초대 메일을 보낸다.

invitee=(mysung stu s1234567) # 자기 ID 추가

for person in $invitee    # Debug!

do

   echo “오늘 저녁식사에 초대합니다 MYS" | \

   mail "${person}"

#   mail "${person}@naver.com"

Done


$ su – stu

암호:

$ mail


모든 명령줄 인수 처리

 모든 명령줄 인수 처리 


for file [ in $* ]

do

...

done


 단어 리스트가 없으면 대신 $@

#!/bin/bash

# perm1.bash 파일*

# 파일의 사용권한과 이름을 프린트한다 

if [ $# -eq 0 ]

then

   echo 사용법: $0 파일*

   exit 1

fi

echo "사용권한 파일"

for file in $*

do

   if [ -f $file ]

   then

      fileinfo=`ls -l $file`

      perm=`echo "$fileinfo" | cut -d' ' -f1`

      echo "$perm $file"

   fi

done


반복문: while & until

 while 문

 조건에 따라 명령어들을 반복 실행 


while 조건식

do

   명령어리스트 

done


 until 문

 조건에 따라 명령어들을 반복 실행 


until 조건식

do

   명령어리스트 

done

#!/bin/bash

# power.bash 

# 2의 1승부터 10승까지 프린트

let i=2

let j=1

while (( $j <= 10 ))

do

   echo '2 ^' $j = $i

   let i*=2

   let j++

done


#!/bin/bash

# power.bash 

# 2의 1승부터 10승까지 프린트

let i=2

let j=1

until ((              ))

do

   echo '2 ^' $j = $i

   let i*=2

   let j++

done


while .vs. until 

#!/bin/bash

# while.bash 

x=1

while [           ]

do

  echo x=$x

  x=`expr $x + 1`

done

#!/bin/bash

# until.bash 

x=1

until [ $x -gt 3 ]

do

  echo x=$x

  x=`expr $x + 1`

done

menu.bash

#!/bin/bash

# 사용법: menu.bash

# 메뉴에 따라 해당 명령어를 실행한다.

echo 명령어 메뉴

stop=0

while (($stop == 0))

do

   cat << MENU

     d : 날짜 시간

     l : 현재 디렉터리 내용

     w : 사용자 보기

     q : 끝냄

MENU

echo -n '? '

read reply

case $reply in

   "d") date;;

   "l") ls;;

   "w") who;;

   "q") stop=1;;

   *) echo 잘못된 선택;;

esac

done


$ menu.bash

명령어 메뉴

d : 날짜 시간

l : 현재 디렉터리 내용

w : 사용자 보기

q : 끝냄

? d

2012년 2월 23일 목요일 오후 07시 33분 27초

d : 날짜 시간

l : 현재 디렉터리 내용

w : 사용자 보기

q : 끝냄

? q


함수

 함수 정의

함수이름()

{

   명령어리스트

}


 함수 호출

함수이름 [매개변수]


#!/bin/bash

# lshead.bash

lshead() {

echo "함수 시작, 매개변수 $1"

date

echo "디렉터리 $1 내의 처음 3개 파일만 리스트"

ls -l $1 | head -4

}

echo "프로그램 시작"

lshead /tmp # 명령줄 인수로 수정하세요

exit 0


$ lshead.bash

프로그램 시작

함수 시작, 매개변수 /tmp

2012. 10. 31. (수) 14:10:10 KST

디렉터리 /tmp 내의 처음 3개 파일만 리스트

합계 968

-rw-r--r--. 1 s2701367   ul2011a      2 10월 21 02:15 1.c

-rw-r--r--. 1 s2701346   ul2011a      3 10월 23 04:21 12.c

-rw-r--r--. 1 s201101608 ul2011a    298 10월 21 21:39 2.5.c


7.8 고급 기능




디버깅

$ bash -vx 스트립트 [명령줄 인수]


#!/bin/bash

# menux.bash 오류 있는 프로그램

echo 명령어 메뉴

명령어 메뉴

stop=0

while (($stop == 0))

do

   cat << MENU

   echo -n '? '

   read reply

   case $reply in

      "d") date;;

      "l") ls;;

      "w") who;;

      "q") stop=1;;

      *) echo 잘못된 선택;;

   esac

done



$ bash -vx menux.bash

#!/bin/bash

# 사용법: menu.bash

# 메뉴에 따라 해당 명령어를 실행한다.

echo 명령어 메뉴

+ echo $'\270\355\267\311\276\356' $'\270\336\264\272'

명령어 메뉴

명령어 메뉴

+ $'\270\355\267\311\276\356' $'\270\336\264\272'

./menux.bash: line 5: 명령어: command not found

stop=0

+ stop=0

while (($stop == 0))

do

   cat << MENU

echo -n '? '

read reply

case $reply in

   "d") date;;

   "l") ls;;

   "w") who;;

   "q") stop=1;;

   *) echo 잘못된 선택;;

esac

done


./menux.bash: line 20: warning: here-document at line 9 delimited by end-of-file

 (wanted `MENU')

./menux.bash: line 21: syntax error: unexpected end of file


shift

 shift 명령어

 명령줄 인수[리스트 변수] 내의 원소들을 하나씩 왼쪽으로 이동


shift [리스트변수]


$ chmod +x perm2.bash

$ ./perm2.bash *

$ ./perm2.bash p*


#!/bin/bash

# perm2.bash 파일*

# 파일의 사용권한과 이름을 프린트 

if [ $# -eq 0 ]

then

   echo 사용법: $0 files

   exit 1

fi

echo "허가권 파일"

while [ $# -gt 0 ]

do

   file=$1

   if [ -f $file ]

   then

     fileinfo=`ls -l $file`

     perm=`echo "$fileinfo" | cut -d' ' -f1`

#    perm=`ls -l $file | cut -d' ' -f1`

     echo "$perm $file"

   fi

   shift

done


디렉터리 내의 모든 파일 처리

 디렉터리 내의 모든 파일 처리

 해당 디렉터리로 이동

 for 문과 대표 문자 *를 사용

 대표 문자 *는 현재 디렉터리 내의 모든 파일 이름들로 대치


cd $dir

for file in *

do

...

done


$ chmod +x count2.bash

$ ./count2.bash /tmp

$ ./count2.bash /dev

$ mknod mypipe p

$ ./count2.bash ./

재귀적 반복(recursion)

 스크립트도 자기 자신을 호출 가능

 어떤 디렉터리의 모든 하위 디렉터리에 대해 동일한 작업을 수행할 때 매우 유용함

 반드시 절대경로로 호출


$ chmod +x rhead.bash

$ rm a.out

$ ./rhead.bash ./


#!/bin/bash

# rhead.bash [디렉터리]

# 대상 디렉터리와 모든 하위 디렉터리 내에 있는 파일들의 헤더를 프린트

#if [ $# -eq 0 ]

#then

#   echo 사용법: $0 directory

#   exit 1

#fi

#if [ ! -d $1 ]

#then

#   echo $0\: $1 디렉터리 아님

#   exit 1

#fi

cd $1

for file in *

do

   if [ -f $file ]

   then

     echo "========== $file ==========="

     head -3 $file

   fi

   if [ -d $file ]

   then

      /home/mysung/ulprog/shellprog/rhead.bash $file

   fi

done

터미널에서 실행

 터미널에서 while 혹은 for 문도 실행


$ for f in *

> do

> echo $f

> done





$ echo $PS2


$ let i=2

$ let j=1

$ while (( $j <= 10 ))

> do

> echo '2 ^' $j = $i 

> let i*=2 

> let j++ 

> done 

2 ^ 1 = 2

2 ^ 2 = 4

…

2 ^ 10 = 1024


(참고) set

 set 옵션

$ set -v (verbose mode)

$ set +v (verbose mode 제거)

$ set -x (실행된 명령에 + +표시, 전달된 매개변수 내용 출력, 디버깅에 좋음)

$ set - (-v와 -x를 무력화 시키고 인수로 매개변수 설정)

$ set -- (double hyphens)로 매개변수 시작 알림

$ set -u (설정되지 않은 변수 만나면 에러 발생)

$ set -k (명령 이름 앞에 적은 것 뿐 아니라, 모든 키워드 인수를 명령의 환경으로 설정)


(예)

$ set - a b c

$ echo $1

$ date

2013. 11. 11. (월) 11:11:11 KST

$ set -- `date`

$ echo $6

KST

$ echo "$@"

2013. 11. 11. (월) 11:11:11 KST

(참고) set

 -x 명령 행 옵션으로 실행되는 디버깅 기능

$ cat set.bash

set -vx a.c

ls $1

set -

echo notset=\"$notset\"

echo goodbye $LOGNAME

set -u

echo notset=\"$notset\"

$ set.bash b.c

…?…  실제로 수행된 명령 앞에 ++ 표시


 쉘 명령 앞에서 변수 배정 정의하면 그 명령으로 변수 값이 export됨

$ cat myname

echo My name is $name and my argument is $1

$ name=MYS  myname  Jay


 set -k로 매개변수를 주어진 모든 키워드(‘=‘) 인수를 명령의 환경에 위치시킴

$ set -k

$ myname  name=MYS  Jay

(참고) junk (= 7장 연습문제 2번 해법)

#! /bin/bash

# junk script

# Initialize variables

fileCount=0     # the number of files specified.

listFlag=0      # set to 1 if the list option (-) is used.

purgeFlag=0     # set to 1 if the purge (-p) option is used.

fileFlag=0      # set to 1 if at least one file is specified.

junk=~/.junk    # the name of the junk directory.

error ()

{

# Display error message and quit

cat << ENDOFTEXT

echo Dear $USER, the usage of junk is as follows:

echo   junk -p means "purge all files"

echo   junk -l means "list junked files"

echo   junk <list of files> to junk them

ENDOFTEXT

exit 1

}

# Parse command line

for arg in $*

do

  case $arg in

    "-p")

        purgeFlag=1        ;;

    "-l")

        listFlag=1        ;;

    "-*")

        echo $arg is an illegal option        ;;

    *)

        fileFlag=1

        fileList[$fileCount]=$arg # append to list

        let fileCount=fileCount+1        ;;

    esac

done




핵심 개념

 단순 변수는 하나의 값(문자열)을 리스트 변수는 여러 개의 값 (문자열)을 저장할 수 있다

 쉘 변수는 크게 환경변수와 지역변수 두 종류로 나눌 수 있다.  환경 변수는 값이 자식 프로세스에게 상속되며 지역변수는 그렇지 않다

 Bash 쉘은 조건, 스위치, 반복 등을 위한 제어구조로 if, case, for, while 등의 문장을 제공한다

 Bash 쉘의 식은 비교 연산, 파일 관련 연산, 산술 연산 등을 할 수 있다 





'myPPT' 카테고리의 다른 글

일제의 경제 수탈  (1) 2015.07.06
지구의 생성  (0) 2015.07.04
사회복지의 역사 in 서양 and 한국  (0) 2015.06.29
중국의 현대시 : 시기별 단계  (0) 2015.06.26
전략캔버스 - 가치곡선  (0) 2015.06.24
Posted by MSNU






favicon

Vorsprung durch Technik

  • 태그
  • 링크 추가
  • 방명록

관리자 메뉴

  • 관리자 모드
  • 글쓰기
  • 분류 전체보기 (993)
    • myPPT (813)
    • 시리즈 (164)
      • 연소 (14)
      • 경제 (5)

카테고리

PC화면 보기 티스토리 Daum

티스토리툴바