과제 1, 과제2 과제1 : 1999년 9월 30일(목)까지 과제 2 : 1999년 10월 15일(금)까지 Vi 편집기를 이용하여 자기소개서(1 페이지 이상)를 작성하고 아래의 디렉토리에 자기 학번으로 디렉토리를 만들고 그 안에 복사하세요. Host: isis isis:/home1/prof/mysung/unixreport/991unix(주간) 또는 992unix(야간) 과제 2 : 1999년 10월 15일(금)까지 ‘Unix 과제 2’ 유인물 참조하여 C 언어로 p 프로그램을 작성하고 그 소스 코드 및 실행 파일을 자기 학번 디렉토리에 복사하세요. 참고 C 언어 프로그램 컴파일 및 실행 # cc 파일이름 (현재 디렉토리에 실행파일 a.out 생성) # a.out 또는 # cc 프로그램파일이름 -o 실행파일이름 # 실행파일이름 Unix
11. Bourne 쉘 프로그래밍 언어. 쉘(Shell) 쉘 프로그램 실행 대화형 명령어 인터프리터 일반적으로 C shell 선호 강력한 프로그래밍 언어 쉘 대본(shell script) 작성위해 Bourne shell 선호 쉘 프로그램 실행 쉘 대본(shell script) = 쉘 프로그램(shell program) = 명령 파일(command file) = 대본(script) 텍스트 파일에 저장된 일련의 시스템 명령 $ cat lsdir if [$# -eq 0] then dir=. else dir=$1 fi find $dir -type d -print 자동 쉘 변수(Automatic Shell Variables) $# : number of positional arguments $0 : command name (Solaris 2.7에 없음) $1, $2 ... : positional arguments $* : $1 $2 …, “$*” = “$1, $2, …” $@ : $1 $2 …, “$@” = “$1”, “$2”, ... $- : Shell options from set command $? : return code from last command $$ : process number of current command $! : process number of last background command 쉘 프로그램 실행 방법 1. $ sh < lsdir (redirection) 2. $ sh lsdir (command-line argument) $ sh lsdir /home/ xx (script 위한 argument 제공 가능) 3. $ chmod a+x lsdir (표준 실행가능 디렉토리에 저장하면 효과적) $ lsdir $ lsdir /home/xx Unix
11. Bourne 쉘 프로그래밍 언어.. 411 쉘 프로그램 예 쉘 변수 $ cat /usr/you/lib/phone-book(전화번호부) dial-a-joke 212-97603838 dial-a-prayer 212-246-4200 dial santa 212-976-3636 dow jones report 323-976-4141 $ echo ‘grep $* /usr/you/lib/phone-book’ > 411 $ chmod a+x 411 $ 411 joke dial-a-joke 212-976-3838 $ 411 dial 비교 $ 411 ‘dow jones’ $ 411 “dow jones” $ echo ‘grep “$*” /usr/you/lib/phone-book’ > 411 쉘 변수 변수명 다음에 바로= $ kc=Kaare $ echo $kc 변수 안에 blank, tab, new line $ kc=“Kaare Christian” 변수명과 다른 문자 혼합 $ ux=Unix $ echo ${ux}tm $ echo “$ux”tm 읽기 전용 쉘 변수 $ flower=tulip $ readonly flower (읽기 전용으로 설정) $ readonly (읽기 전용 변수 출력) Unix
11. Bourne 쉘 프로그래밍 언어... 쉘 변수 export 쉘 변수를 대화형으로 사용하기 사용자 생성 쉘 변수는 현재 쉘에 국한 export로 쉘이 생성한 모든 명령에 사용 가능하게 $ cat foolilike echo $pn butter is yummy $ pn=peanut $ foodilike butter is yummy $ export pn peanut butter is yummy 쉘 변수를 대화형으로 사용하기 $ doc=/home/td/c/mon/src/doc $ ls $doc $ ls -i $doc/*.txt $ tmonprint=$doc/tmonprint 표준 쉘 변수 # set (자동 쉘변수 제외한 모든 표준 및 사용자 생성 변수의 전체 리스트 출력) $HOME $PATH $CDPAT $IFS $LOGNAME $MAIL 또는 MAILPATH $MAILCHECK $SHELL $SHACCT $PS1 $PS2 $TERM Unix
11. Bourne 쉘 프로그래밍 언어…. 검색경로(The Search Path) 널과 비지정 변수 다루기 (.): (null directory, 현재 디렉토리) /bin (최소한의 시스템 작동을 위한 표준 실행파일들) /usr/bin (표준 실행파일들) /usr/X/bin (X 윈도우 소프트웨어) /usr/ucb (Berkeley 명령들) $ echo $PATH (현재 검색경로 출력) $ PATH=:$PATH (현재 디렉토리 포함) 가능한한 적게 검색하게 bin 디렉토리 너무 크지 않게 유지 검색경로 수정 않게 널과 비지정 변수 다루기 $ set -u (비지정 변수 사용시 경고) ${var:-word} ${var:=word} ${var:?word} ${var:+word} $ echo $name Spade Spade $ echo ${name:-Sam} Spade Sam Spade ... $ echo ${name:=Sam} Spade Unix
11. Bourne 쉘 프로그래밍 언어….. 특수 문자 인용하기(Quoting Special Characters) 인용 방법 \ 다음 글자 인용 : 한 글자 인용 ‘ ’ 로 묶은 글자 인용 : 다른 해석 없음 “ ” 로 묶은 글자 중 \, “, ”, $ 제외하고 인용 : 명령과 파라미터 대치 발생 $ echo $HOME $ echo ‘$HOME’ $ echo \$HOME $ echo “$HOME” $ echo Howdy | wc $ echo Howdy \| wc $ echo ‘Howdy | wc’ $ echo “Howdy | wc” $ echo one two three $ echo “ one two three” 명령 종결 상태(Command Exit Status) $? 에 쉘에 의해 실행된 마지막 명령의 종결 상태 저장 $ ls -d /home/John $ echo $? 단순 조건문(Simple Conditionals) $ ls -d /home/kc > /dev/null && echo FOUND (&&는 0 종결상태에서만 실행) $ ls -d /usr/xyz || echo No /usr/xyz $ true && echo True $ false || echo False 단순 명령, 파이프 라인, 리스트 파이프라인은 일련의 단순 명령들 리스트는 일련의 파이프라인들, {} 리스트 요소 분리 ; (순차 실행) && (조건 true 실행) || (조건 false 실행) & (백그라운드 실행) Unix
11. Bourne 쉘 프로그래밍 언어:. 쉘 프로그램 매개변수 If 조건문 $ cat rev-4 if test $# -eq 4 (또는 [$# -eq 4]pseudonym) then echo $4 $3 $2 $1 else echo Usage: $0 arg1 arg2 arg3 arg4 Shell script안에서는 한번에 9개 매개변수만 다룰 수 있으므로 shift 필요 $ cat shiftdemo echo $# : $1 $2 $3 $4 $5 $6 $7 $8 $9 shift (첫번 매개변수 없어지고 작은 쪽으로 이동) [ $# -gt 0 ] && shiftdemo $1 $2 $3 $4 $5 $6 $7 $8 $9 10개 이상 매개변수 다루기 위해 $ cat shiftdemo1 [ $# -gt 0 ] && shiftdemo “$@” $ shiftdemo1 a b c d e f g h i j k l 의 결과는? $ shiftdemo a “x y x” b (cf.) [ $# -gt 0 ] && shiftdemo $@ If 조건문 if condition-list then list elif condition-list else list fi $ cat errormonitor if test -r errorfile (p260 참조) then lp errorfile rm errorfile else echo “\nNo errors this hour.” | lp Unix
11. Bourne 쉘 프로그래밍 언어:.. While과 Until 조건 루프 For 문 파일 사라지길 기다림 while test -r lockfile do sleep 5 done = while test -r lockfile; do sleep 5; done 파일 생성 기다림 while test ! -r proceedfile do sleep 1 = until test -r proceedfile 구조적 명령(Structured Commands) until test -r stopfile; do >sleep 2; echo Hello; done & Hello … > Stopfile For 문 $ cat fruits for fruit in apples pears oranges do echo $fruit are fruits done $ cat echoecho for arg echo $arg $ cat revargs1 list=“” list=“$arg $list” Unix
11. Bourne 쉘 프로그래밍 언어:... Case 문 Break와 Continue $ cat breeds for breed do case $bread in arabian|palomino|clydesdale) echo $breed is a horse;; jersey|guernsey|holstein) echo $breed is a cow;; *) echo $breed is not in our catalog;; esac done Break와 Continue while true test -r lockfile || break sleep 5 p248 breads1 참조 명령대치(Command Substitution) $ now=`date`(reverse single quote, accent grave, cf.’:single quote, accent acute(aigu)) $ sum = `expr 5 + 13` (expr: 산술연산) $ count=10 $ echo $count 10 $ count=`expr $count + 1’ 11 쉘 대치 명령어 대치: `…` 사이 명령결과로 대치 파라미터 대치(변수 대치): “$”로 시작하는 쉘 변수들을 그 값으로 대치 공백 해석: field separator 만날 때마다 단어 나눔, 단 인용된 단어안의 spaces, tabs, new lines 는 무시되고 널 단어는 제거됨 파일명 생성: metacharacters 검사하여 알파벳 순으로 대치 Unix
11. Bourne 쉘 프로그래밍 언어:…. Set-변수 출력과 쉘 운영 모드 지정 Here Documents 쉘 함수 p255 표11.2 참조 $ set -v (verbose mode) $ set +v (verbose mode 제거) $ set -x (실행된 명령에 + 표시, 전달된 매개변수 내용 출력, 디버깅에 좋음) --(double hyphens)로 매개변수 시작 알림 $ date 1999년 9월 29일 수요일 오후 02시 38분 03초 $ set -- `date` $ echo $6 02시 $ echo “$@” -x 명령행 옵션으로 실행되는 디버깅 기능 p257 opts 참조 쉘 명령 앞에서 변수 배정 정의하면 그 명령으로 변수 값이 export됨 $ cat myname echo My name is $name and my argument is $1 $ name=george myname john set -k로 매개변수를 환경변수 취급 $ myname name=george john Here Documents 쉘 프로그램 안에서 표준입력을 일시적으로 재지정 mail operator <<! …the problem again... ! $ cat 411 grep “$*” <<End dial-a joke 212-976-3838 dial-a-prayer 212-246-4200 dial-a-santa 323-976-3636 dow jones report 212-076-4141 End 쉘 함수 name() { statements } 사용되기 전에 정의되어야함 p253 fna 참조 Unix
11. Bourne 쉘 프로그래밍 언어::. Expr-표현식 평가 Test-조건평가 non-zero result: true exit status otherwise: false exit status metacharacters 연산자들은 \로 인용 p262 표11.4 참조 $ cat countto count = 0 [ $# -ne 1] && { echo “usage: countto val”; exit;} while [$1 -gt $count ] do count = `expr $count + 1` echo $count done : 연산자 이용한 스트링 발췌(string extraction): p263 예제 참조 $ tty /dev/pts002 expr `tty` : “.*\(…\)\$ 또는 ‘.*\(…\)$’ Test-조건평가 비교 유형 파일 조사 문자열 비교 수치 비교 동의어 [] p260 표11.3 참조 $ if test -r /etc/motd >then >echo Readable >fi Readable $ [-d /bin ] && echo /bin is a directory $ [ $HOME = `pwd` ] || echo we are not home now $ [40 -lt `ls | wc -l` ] && echo too many files here Unix
11. Bourne 쉘 프로그래밍 언어::.. Ulimit-자원제한의 지정과 출력 getopts-스크립트에서의 옵션 관리 약한 제한: -a 강한 제한: -Ha p264 표11.5 참조 getopts-스크립트에서의 옵션 관리 표준 옵션 -abc를 쉘 스크립트 옵션 플래그 -a -b -c 로 분리 getopts 2 매개변수 option flags의 리스트 option flag를 저장할 변수 명령행 옵션 문자를 하나씩 떼어 변수에 저장 처리할 변수 없으면 False status 돌려줌 $OPTARG: 매개변수 가지는 옵션의 매개변수 저장 $OPTIND: 옵션이 아닌 첫번째 참 매개변수(non-option argument)의 인덱스 저장 $ cat opts2 while getopts UVX op do case $op in U) set -u;; V) set -v;; X) set -x;; esac shift `expr $OPTIND - 1` echo The body of the shell script… $ opts2 -VX -o 허용 opts2: p266 opt3 꼭 보세요! Bourne 쉘의 내장 명령 p267 표11.6 참조 Unix
12. 쉘 프로그래밍. 언제 쉘 프로그래밍? 몇 명의 사용자가 로그인? $ cat logusers1 (전주에 만들어진 파일 삭제하며) lastday=never while true do set -- day=$4 (한글의 경우 요일) [$day != $lastday ] && > /usr/adm/$day # (>/usr/adm/$day로 빈파일 생성) who | wc -l >> /usr/adm/$day lastday=$day sleep 600 (10분) done logusers1 10분 마다 반복 수행되어야 함 background job으로 계속 실행해야 함 cron process로 10분 마다 실행하면 안됨 day 파일 10분 마다 삭제됨 process table 포화 C 프로그램 경우 /etc/utmp (login 기록 파일) 조사 등 프로그래밍 어려움 쉘 프로그램이 유리 언제 쉘 프로그래밍? 실행시간 많이 필요 속도가 중요할 때는 다른 프로그래밍 언어가 유리 표준 Unix 시스템 명령이 많이 사용되는 경우 쉘 프로그래밍 이 유리 GUI-style program은 C 언어가 유리 몇 명의 사용자가 로그인? $ cat nusers who | wc -l $ cat nusers1 echo `who | wc -l` users are on the system $ cat logusers while true do set -- `date` day=$4 (한글의 경우 요일) who | wc -l >> /usr/adm/$day sleep 600 (10분) done Unix
12. 쉘 프로그래밍.. 서브디렉토리 출력하기 현재 서브트리에 있는 파일 출력 $ cat lsdir ls -l $1 | grep ‘^d’ ($1 -> $@) $ cat lsdir2 (여러 arguments 처리) for i do ls -l $i | grep ‘^d’ done $ cat lsdir3 (no argument 처리) [$# -eq 0] && set -- . $ cat lsdir4 (test 이용) for i in $1/* [ -d $i ] && echo $i $ cat lsdir5 (no argument 처리) for i in ${1:-”.”}/* do [ -d $i ] && echo $i done 현재 서브트리에 있는 파일 출력 $ ls -R $ find . -print | sort | pr -4t $ find . -type d -print $ for i in * > do > [ -d $i ] && echo $i > done $ cat lstree1 [ $# -eq 0 ] && set -- . for i in $1/* [ -d $i ] && { echo $i; sh lstree1 $i } Unix
12. 쉘 프로그래밍... 명령행 재평가를 위한 eval 명령 사용 $ cat lstree2 [ $# -eq 1 ] && cd $1 ls | { while read i do [ -d $i ] && { echo $i; sh lstree2 $i } done $ cat findbyname [ $# -ne 1] && {echo Usage: $0 filename; exit ;} find . -name “$1” -print $ findbyname ‘*.ltr’ ‘*.ltr’ 이유 로그인 쉘에서 * 확장(expand) 하지 않도록 만일 인용 않으면 현재 디렉토리에 있는 모든 .ltr 파일만을 현재와 하위 디렉토리에서 찾음 “$1” 이유 스크립트 실행하는 서브 쉘이 * 확장하지 않도록 명령행 재평가를 위한 eval 명령 사용 $ cat revargs count=$# while test $count -gt 0 do eval echo -n \$$count echo -n “ “ count=`expr $count -1` done echo $ revargs A B C 비교 $ cat revargsa echo -n \$$count $ revargsa A B C Unix
과제 3...10월 15일까지 문제 1: 매개변수가 3개(-a, -b, -c)가 있는지 조사하고 만일 없으면 사용자에게 매개변수를 3개 치도록 프롬프트를 내 주고, 매개변수가 각각 -a, -b, -c 이면 True를 출력하고 아니면 False를 출력하는 쉘 프로그램을 작성하라. (p239 rev-4 참조) 문제 2: 다음은 60초 마다 한번씩 mary가 로그인 했는지 조사하는 쉘 프로그램이다. 이 프로그램을 참조하여 매개변수로 입력된 사람이 로그인 했는지 조사하는 쉘 프로그램을 작성하되, 한 사람 이상도 살펴볼 수 있도록 하라. (p157 egrep 참조) $ cat mary PATH=/bin:/usr/bin until who | grep mary do sleep 60 done 문제 3: 다음의 pick은 매개변수로 입력된 인수들을 취사선택하는 쉘 프로그램이다. 이 프로그램을 코딩하여 실행해 보고, 명령 줄에 아무것도 없으면 표준 입력으로부터 인수를 읽는 pick을 작성하라. 빈 칸을 적절히 다루고, q 도 잘 동작하도록 하라. $ cat pick PATH=/bin:/usr/bin for i do echo -n “$i? ” > /dev/tty read response case $response in y*) echo $i ;; q*) break esac done < /dev/tty Unix