40
4 장 . Bourne 장 장장장장장장 장장장

4 장 . Bourne 셸

Embed Size (px)

DESCRIPTION

4 장 . Bourne 셸. 컴퓨터공학과 강성인. Bourne 셸 기능. 내장 명령어. 리다이렉션. 프로그래밍 언어. 명령열. 변수. 시작하기. {...}. export. readonly. profile. trap. set. read. &. for. case. while. if. 4.1 Bourne Shell 에 추가된 기능들. 변수를 설정하고 접근하는 방법들 조건 분기 , 루핑과 인터럽트 조작을 지원하는 내장된 프로그래밍 언어 - PowerPoint PPT Presentation

Citation preview

4 장 . Bourne 셸

컴퓨터공학과강성인

4.1Bourne Shell 에 추가된 기능들

변수를 설정하고 접근하는 방법들 조건 분기 , 루핑과 인터럽트 조작을 지원하는 내장된

프로그래밍 언어 기존의 리다이렉션과 명령열 운영의 확장 새로운 몇 개의 내장 명령어

Bourne 셸 기능

내장 명령어 리다이렉션 프로그래밍 언어 명령열 변수 시작하기

trap set read <& >& for case while if {...} export readonly profile

4.2 시작하기

/bin/sh sh 명령어 : 스크립트나 터미널로부터 수동적 호출 가능 대화형셸

시작시 자신의 홈 디렉토리에서 “ .profile” 화일을 찾음 . “.profile” 의 존재 유무에 관계없이 prompt 를 내보내고 사용자의

명령을 기다림

비대화형셸 : 어떤 시작 화일도 읽지 않음

init

login

sh

터미널 포트를 열어 표준 입출력 에러방향 설정

/bin/login 프로그램 실행

/bin/sh 실행 (login shell)/etc/profile 실행사용자 홈 디렉토리의 .profile 검사하여 실행

login : sikangpasswd:Welcome!$_

Bourne 셸의 시작

4.3 변수 변수의 생성 및 할당

변수가 존재하면 새로운 값으로 바꾸고 , 존재하지 않으면 자동적으로 만들어짐 .

새롭게 생성된 변수는 항상 지역변수 .

공백은 “ ” 로 묶어준다 .

문자열을 저장 ( 수치도 문자열로 취급 )

“=“ 좌우에 공백이 있어서는 안됨

{name=value}+

$ firstname=sungin lastname=kang //2 개 변수의 생성$ echo My name is $firstname $lastnameMy name is sungin kang$ name=sungin kangkang: 없음$ name="sungin kang“ // 문자열은 따옴표로 표시$ echo $namesungin kang$_

변수로의 접근 1 $name : name 의 값으로 대치 ${name} : name 의 값으로 대치 . 변수 이름의 일부로 번역되는

문자가 숫자가 표현식 다음에 올 때 유용

$ verb=sing // 변수할당$echo I like $verbing //verbing 변수는 없다I like $echo I like ${verb}ing I like singing$_

변수로의 접근 2 ${name-word} : 설정 되었으면 name 의 값으로 대치 , 그렇지 않으면 word 의 값으로 대치 ${name+word} : name 이 설정되었을 때 word 만 대치

$ startDate=${startDate-"`date`"} // 설정되어 있지 않으면 date 실행$ echo $startDate2004 년 4 월 6 일 화요일 오후 09 시 18 분 34 초$ flag=1 // 변수 할당$ echo ${flag+'flag is set'} flag is set$ echo ${flag2+'flag is set'} // 결과 “ null”$_

변수로의 접근 3 ${name=word} : name 이 설정되지 않았으면 word 를 할당하고 name 의 값으로 대치 ${name?word} : name 이 설정되지 않았으면 word 는 표준 에러 채널로 표시되고 그 셸은 종료 . $ echo x=${x=10} // 디폴트 값 할당x=10$ value=${x?'x not set'} // 접근 성공$ echo $value10$ value=${grandTotal?'grand total not set'} // 미설정grandTotal: grand total not set$_

표준 입력으로부터 변수 읽기

표준 입력으로부터 한 줄을 읽고 명시된 변수들에게 그 줄로부터 연속된 단어들을 할당한다 .

read {variable}+

$ cat script.shecho "enter your name,age: \c"read name age // 두 변수로 읽기echo your name is $nameecho your age is $age$ script.shenter your name,age: Glass 20 your name is Glass // 첫 번째 변수가 첫째 단어를 저장your age is 20 // 마지막 변수가 나머지를 저장$_

변수의 범위 전환

환경변수로 범위 전환시키도록 명시된 변수들을 표시 환경변수는 대문자 사용

export {variable}+

$ export // 현재까지 export 된 변수 표시반출 (export) LOGNAME반출 (export) PATH$ DATABASE=/dbase/db // 지역변수 생성$ export DATABASE //export$ export //export 된 변수 목록 추가반출 (export) DATABASE반출 (export) LOGNAME반출 (export) PATH$ sh // 서브셸 생성$ echo $DATABASE // 복사본 상속 ( 환경변수의 특성 )/dbase/db$ ^D

읽기 전용 변수

환경변수로 전환된 변수의 읽기 전용 상태는 상속되지 않음

readonly {variable}+

$ passwd=Shazam // 지역변수 할당$ echo $passwdShazam$ readonly passwd // 읽기전용변수$ passwd=Phoombahpasswd: 읽기 전용임 // 수정 안됨$ export passwd // 변수를 export$ sh // 서브셸 실행$ passwd=Alasca // 읽기전용변수 상태 상속 안됨$ echo $passwdAlasca$ ^D$ echo $passwdShazam$_

미리 정의된 지역 변수 일부 셸 변수들은 미리 정의 되어 있어 일반 지역 변수 명으로 사용 할 수

없다 .

이름 값$@ 모든 인수의 개별적으로 인용된 목록 ( 각각의 문자열 )

$# 위치 인수의 수$? 마지막 명령의 반환 값$! 마지막 후면 명령의 프로세스 id

$_ 명령 줄로부터 혹은 내장 명령어 set( 나중에 설명 ) 에 의해 할당된 현재 셸 옵션

$$ 이 셸의 프로세스 ID

$0 현재 명령어 ( 셸 스크립트 ) 의 이름$n 명령줄의 n 번째 인수

$* 모든 명령 줄 인수의 목록 ( 하나의 문자열 )

$ cat script.shecho argument num : $#echo argument unit : $@echo first argument : $1echo second argument : $2echo command name : $0echo argument unit\('$*'\) : $*echo process ID : $$$ script.sh a b c dargument num : 4argument unit : a b c dfirst argument : asecond argument : bcommand name : script.shargument unit($*) : a b c dprocess ID : 9887$_

$ sleep 1000 &9888$ kill $!9888 종료됨 (Terminated)$ echo $!9888$ ls script.shscript.sh$ echo $?0$ llslls: 없음$ echo $?1$

미리 정의된 환경변수

이름 값

$IFS 셸이 명령어를 실행하기 전 명령 줄을 토큰화 시키는 경우 , 설정된 문자를 분리자로 사용 . 공백 , tab, newline 문자를 포함

$PS1 명령 라인 프롬프트 형태를 제어하며 디폴트로 $ 를 갖음 . 명령줄 프롬프트를 변경하려면 $PS1 을 새로운 형태로 지정 .

$PS2 더 많은 입력이 셸에 의해 요구될 때 명령 줄의 보조 프롬프트 형태를 제어 , 디폴트로 >을 갖음 . 프롬프롬트를 변경시 새로운 형태로 지정해 준다 .

$SHENV 설정되어 있지 않으면 , 새로운 셸이 생성될 때 셸은 사용자의 홈 디렉토리에서 “ profile” 시작하기 화일을 찾음 . 변수가 설정되어 있으면 셸은 $SHENV에 의해 명시된 디렉토리에서 찾음

$ PS1="sh?“ // 새로운 프롬프트 생성sh?oldIFS=$IFS // IFS 의 이전 값 기억sh?IFS=":“ // 단어 분리자를 “ :” 으로 변경sh?ls:script.sh // 실행 성공script.shsh?string="a long \ > string“ // >는 보조 프롬프트sh?echo $stringa long stringsh?PS2="???“ // 보조 프롬프트 변경sh?string="a long \???string"sh?

4.4 산술 계산

expr expression expression 을 계산하여 그 결과를 표준 출력으로 보낸다 . expression 은 연산자와 연산 항으로 구성되고 공백으로 분리 . 모든 셸 메타문자들은 \ 로 특수기능을 상실한다 .

연산자 의미\* / % 곱셉 , 나눗셈 , 나머지

+ - 덧셈 , 뺄셈= \> \>= \< \<= != 비교연산자 ( 참 ->1, 거짓 ->0)

\& 논리적 and

\| 논리적 or

※ 계산 순서를 명시적으로 제어하기 위해서는 \( \) 를 사용

$ x=1$ x=`expr $x + 1`$ echo $x2$ x=`expr 2 + 3 \* 5` //* 계산후 + 계산$ echo $x17$ echo `expr \( 2 + 3 \) \* 5` //\( \) 먼저 계산25$ echo `expr \( 4 \> 5 \)`0 //거짓이므로 0$ echo `expr \( 4 \> 5 \) \| \( 6 \< 7 \)`1 //참이므로 1

$ echo 'expr length "cat" ' //cat 의 길이 구하기3$ echo 'expr Substr "donkey" 4 3' // 부문자열 추출key$ echo 'expr index "donkey" "ke" ' // 부문자열 위치4$ echo 'expr match "smalltalk" '.*lk' ' // 일치하는 문자열 길이9

문자열 연산자

연산자 의미Length 문자열의 길이를 반환Substr 부 문자열 추출Index 부 문자열 위치match 일치하는 문자열의 길이를 반환

4.5 조건식

expression 이 참이면 0 인 종료 코드를 돌려주고 그렇지 않으면 0이 아닌 종료 상태를 반환한다 .

test 라는 명령어 대신에 두 번째 형식 “ [ ]” 를 사용하는 경우 대괄호와 expression 사이에 공백이 추가되어야 한다 .

test expression[ expression ]

test 명령의 옵션 ( 숫자 )

형식 의미Int1 –eq int2 정수 int1 이 정수 int2 와 같으면 참Int1 –ne int2 정수 int1 이 정수 int2 와 같지 않으면 참Int1 –gt int2 정수 int1 이 정수 int2 보다 크면 참Int1 –ge int2 정수 int1 이 정수 int2 이상이면 참Int1 –lt int2 정수 int1 이 정수 int2 보다 작으면 참

Int1 –le int2 정수 int1 이 정수 int2 이하이면 참

test 명령의 옵션 ( 파일 )

형식 의미-b filename Filename 이 블록 특수 파일로 존재하면 참-c filename Filename 이 문자 특수 파일로 존재하면 참-d filename Filename 이 디렉토리로 존재하면 참

-f filename Filename 이 비디렉토리로 존재하면 참

-g filename Filename 이 set-group-ID 파일로 존재하면 참-h filename Filename 이 심볼릭 링크로 존재하면 참

-k filename Filename 이 존재하고 sticky 비트가 설정되어 있으면 참-p filename Filename 이 명명된 파이프로 존재하면 참-r filename Filename 이 읽을 수 있는 파일로 존재하면 참-s filename Filename 이 하나 이상의 문자를 포함하면 참-u filename Filename 이 set-user-ID 파일로 존재하면 참-w filename Filename 이 쓰기 가능 파일로 존재하면 참-x filename Filename 이 실행 가능 파일로 존재하면 참

test 명령의 옵션 ( 문자열 , 논리 연산 )

형식 의미-l string string 의 길이가 0 이 아니면 참-n string string 이 적어도 하나의 문자를 포함한다면 참-z string string 의 길이가 0 이면 참str1=str2 str1 이 str2 와 같으면 참str1 !=str2 str1 이 str2 와 같지 않으면 참string string 이 널이 아니면 참!expr expr 이 거짓이면 참

expr1 –a expr2

expr1 과 expr2 가 모두 참이면 참

expr1 –o expr2

expr1 또는 expr2 가 참이면 참

\( expr \) 그룹 표현식을 위해 \( 과 \) 를 사용

4.6 제어구조 (Case-in-esac)

패턴에 대응하는 것을 찾아 그 패턴의 명령들을 실행하는 다중 선택형식 expression 은 문자열로 계산되는 식이고 , pattern 은 대표문자를 포함할 수 있음 expression 을 계산한 후 순차적으로 pattern 과 비교하여 맨 처음 일치하는 패턴에

연관된 명령어 리스트가 실행된다 .

파이프 심볼 (|) 을 사용하여 다수의 단어들로 하나의 pattern 을 형성할 수 있다 .

case expression inpattern { | pattern }* )list;;esac

$ menu.shmenu test program 1 : print the date. 2,3 : print the current working directory 4 : exit your choice? 1 2007 년 3 월 31 일 토요일 오후 06 시 39 분 04 초 1 : print the date. 2,3 : print the current working directory 4 : exit your choice? 2 /home/sikang 1 : print the date. 2,3 : print the current working directory 4 : exit your choice? 3 /home/sikang 1 : print the date. 2,3 : print the current working directory 4 : exit your choice? 4 $

$ cat menu.sh#! /bin/shecho menu test programstop=0while [ $stop -eq 0 ] #완료 시 까지 반복do cat << ENDOFMENU 1 : print the date. 2,3 : print the current working directory 4 : exitENDOFMENU echo echo 'your choice? \c' read reply echo case $reply in "1") date ;; "2"|"3") pwd ;; "4") stop=1 ;; *) # 디폴트 echo illegal choice # 오류 ;; esacdone

4.6 제어구조 (for-do-done)

단어 리스트 안의 각 word 를 통해 변수 name 의 값을 반복하며 , 각 반복 후에 list 에 있는 명령을 실행

단어 리스트가 제공 되지 않으면 $@($1,$2,...) 이 사용된다 .

for name [ in { word } * ]

do

list

done

$ cat for.sh#! /bin/shfor color in yellow green bluedo echo one color is $colordone$ for.shone color is yellowone color is greenone color is blue$_

$ cat for.sh#! /bin/shfor colordo echo one color is $colordone$ for.sh yellow red blueone color is yellowone color is redone color is blue$_

단어 리스트 제공 단어 리스트 제공 안됨

4.6 제어구조 (if-then-fi)

if list1then list2elif list3 // 여러 번 반복 가능then list4else //1 번 이하 수행 list5fi

if list1

list2elif list

3

True

True

False

False

list4 list5

$ cat if.sh#! /bin/shecho 'enter a number: \c'read numberif [ $number -lt 0 ]then echo negativeelif [ $number -eq 0 ] then echo zeroelse echo positivefi

$ if.shenter a number: 1positive$ if.shenter a number: -1negative$ if.shenter a number: 0zero

until list1

do

list2

done

4.6 제어구조 (until-do-done)

일련의 명령어들이 실패되는 동안 ( 결과가 거짓 ) 명령을 반복 실행한다 .

$ cat until.shx=1until [ $x -gt 3 ]do echo x=$x x=`expr $x + 1`done$ until.shx=1x=2x=3$

while list1

do

list2

done

4.6 제어구조 (while-do-done)

일련의 명령어들이 성공되는 동안 ( 결과가 참 ) 명령을 반복 실행한다 .

$ multi.shUsage: multi number$ multi.sh 51 2 3 4 52 4 6 8 103 6 9 12 154 8 12 16 205 10 15 20 25$

$ cat multi.shif [ "$1" -eq "" ]; then echo "Usage: multi number" exitfix=1while [ $x -le $1 ]do y=1 while [ $y -le $1 ] do echo `expr $x \* $y`"\t\c" y=`expr $y + 1` done echo x=`expr $x + 1`done

4.6 제어구조 (break, continue)

break : 반복문의 강제 종료 continue : 반복문의 처음으로 분기

구구단 예제 : 입력한 숫자 까지만 구구단을 출력

$ multi2.shenter a number: 41*1= 1 1*2= 2 1*3= 3 1*4= 4 1*5= 5 1*6= 6 1*7= 7 1*8= 8 1*9= 92*1= 2 2*2= 4 2*3= 6 2*4= 8 2*5= 10 2*6= 12 2*7= 14 2*8= 16 2*9= 183*1= 3 3*2= 6 3*3= 9 3*4= 12 3*5= 15 3*6= 18 3*7= 21 3*8= 24 3*9= 274*1= 4 4*2= 8 4*3= 12 4*4= 16 4*5= 20 4*6= 24 4*7= 28 4*8= 32 4*9= 36$

$ cat multi2.sh#! /bin/shecho "enter a number: \c"read stopx=1while [ $x -le 9 ]do y=1 while [ $y -le 9 ] do echo "$x*$y=" `expr $x \* $y`"\t\c" y=`expr $y + 1` done echo if [ $x -eq $stop ] then break fi x=`expr $x + 1`done

4.6 제어구조 (trap)

번호가 붙여진 signal 을 받을 때마다 셸에게 command 를 실행하도록 지시

여러 개의 signal 이 받아들여지면 번호순으로 trap 됨 signal 번호 0 이 지정되면 , 셸이 종료됐을 때 command 가

실행됨

trap [ [ command ] { signal } + ]

$ cat trap.sh#! /bin/shclearcount=1trap break 2while [ 1 -gt 0 ]do echo $count: infinite loop. sleep 1 count=`expr $count + 1`doneechoecho end loop.echo$_

1: infinite loop.2: infinite loop.3: infinite loop.^Cend loop. $_

4.8 그 밖의 내장 명령어 read 명령어 (.)

텍스트파일의 내용을 실행 실행 허가권이 필요 없음 파일 실행 시 현재 셸에서 실행 (파일이 설정한 모든 지역 변수가 현재 셸의 지역 변수임 )

set 명령어 shell옵션의 설정을 on또는 off 시킬 수 있다 . 옵션을 on 시키려면 옵션에 –를 붙이고 off 시키려면 + 를 옵션에 붙인다 .

셀 프로그램을 디버깅 할 때 유용

옵션 의미-e 명령이 실패하면 ERR 트랩이 실행되고 프로그램이 종료된다 .

-n 명령을 실행하지 않고 받아들인다 .

-t 다음 명령을 실행하고 종료한다 .

-u 비설정 변수를 만나게 될 때 에러를 발생한다 .

-v 읽은대로 셸 명령을 에코한다 .

-x 실행한대로 셸 명령을 에코한다 .

- -x 와 – v 플래그를 끊고 “ -” 문자를 인수로 처리한다 .

$ cat script2.shset -vx a.c # 디버그 추적을 설정하고 $1 을 덮어 쓴다 .ls $1set - # 추적중지echo goodbye $LOGNAMEecho $notsetset –u # 미설정 변수 접근 시 오류 발생echo $notset$ script2.shls $1 //-v옵션에 의한 출력+ ls a.c //-x옵션에 의한 출력a.c // 정상 출력set - //-v옵션에 의한 출력+ set - //-x옵션에 의한 출력goodbye sikang // 정상 출력 script2.sh: notset: 파라미터가 설정되지 않음 // 미설정 변수 접근$_

4.9 리다이렉션 파일 기술자 (file descriptor)

유닉스에서 파일 ,파이프 ,및 소켓등 모든 입출력 객체들은 파일 기술자라는 메커니즘을 통해 커널에서 처리된다 .

파일 기술자는 0~19 까지 값을 갖는다 . 특히 처음 3 개의 파일 기술자는 다음과 같은 특수한 의미를 갖는다 . 0: 표준 입력 , 1: 표준 출력 , 2: 표준 에러

$ man ls > ls.txt페이지를 다시 포맷 중입니다 . 기다려 주십시오 ... 완료$ man ls > ls.txt 2>err.txt // 표준에러를 “ err.txt” 로 출력$ cat err.txt페이지를 다시 포맷 중입니다 . 기다려 주십시오 ... 완료$ man ls>ls.txt 2>&1 // 표준에러를 표준출력으로 연계

4.9순차적 명령열

명령어 그룹은 서브셸에서 실행 중괄호를 사용한 순차적 명령열은 부모셸에서 직접 실행 중괄호와 명령어 사이에 공백 필수 , 중괄호 닫기 전에는 “ ;” 을 붙여

준다 .$ pwd/home/sikang$ (cd /; pwd; ls | wc -l)/ 38$ pwd/home/sikang$ { cd /; pwd; ls | wc -l; } / 38$ pwd/$