6. C 셸
6.1 소개 Shell 의공통적인기능이외에 C Shell 에추가된기능들 변수를설정하고접근하는여러가지방법 조건분기, 루프, 인터럽트조작을지원하는내장프로그래밍언어 별명을사용한주문화된고유명령어 히스토리메카니즘을이용한그이전명령어로의접근 개선된작업제어 새로운내장명령어와기존명령어의개선 /bin/csh 시작순서 1$HOME/.cshrc 2 /etc/.login ( 로그인할때만 ) 3 $HOME/.login ( 로그인할때만 ) 6.2 시작하기.cshrc (run commands): 자주쓰이는별명을설정함.login : $TERM, $PROMPT, $PATH 등의변수값을설정함 ( 예 ).cshrc ( 예 ).login Unix 시스템 2
6.3 변수 1 지역변수 ( 단순변수, 리스트변수 ) 2 환경변수 단순변수의값할당 set {name [= word]}* ( 예 ) % set 모든지역변수의리스트가나타남 % set name = M.Y. Sung 단순변수로의접근 $name % set name = "M.Y. Sung" % echo $name 변수 name 의값 ( 독립사용할때 ) ${name} 변수 name 의값 ( 접속사용할때 ) ${?name} 변수 name 의설정되어있으면 1, 아니면 0 의값 Unix 시스템 3
6.3 변수 ( 예 ) % set verb = sing % echo I like $verbing verbing: undefined variable % echo I like ${verb}ing I like singing ( 예 ) % cat flag.csh 리스트변수의값할당 # set flag flag 를 null 문자로설정함 if (${?flag}) then echo flag is set endif % flag.csh flag is set set {name = ( {word}* ) }* ( 예 ) % set colors = ( red yellow green ) % echo $colors red yellow green Unix 시스템 4
6.3 변수 리스트변수로의접근 1 $name[selector] 리스트변수 name 의값 ( 독립사용할때 ) 2 ${name[selector]} 리스트변수 name 의값 ( 접속사용할때 ) 3 $#name 리스트변수 name 의원소들의개수 ( 독립사용할때 ) ( 예 ) $#argv : 입력라인매개변수의개수 4 ${#name} 리스트변수 name 의원소들의개수 ( 접속사용할때 ) Unix 시스템 5
6.3 변수 cf. selector: start-end 형태, start 가명시안되면 1 로간주, * 는모든범위 ( 예 )% set colors = ( red yellow green ) % echo $colors[1] red % echo $colors[2-3] yellow green % echo $colors[4] Subscript out of range % echo $#colors 3 리스트변수의추가 원래의리스트에원소를더하고, 이들을괄호로묶어원래변수로치환 ( 예 ) %set colors = ( red yellow green ) %set colors[4] = pink Subscript out of range %set colors = ( $colors blue ) %echo $colors red yellow green blue Unix 시스템 6
6.3 변수 C shell 에미리정의된여러지역 / 환경변수들 $?0 $< $argv $cdpath $cwd $echo $home $history $histchars $mail $noglob $notify $path $prompt $shell $status $time $verbose $savehist $noclobber $nonomatch $ignoreeof ( 예 ) % cat var5.csh [ 교재 p249] echo -n "please enter your name: " set name = $< # take a line of input echo hi $name, your current directory is $cwd Unix 시스템 7
6.3 변수 환경변수의값할당 setenv name word ( 예 )% setenv TERM vt100 % echo $TERM 미리정의된환경변수 1 공통적으로미리정의된환경변수 $HOME $PATH $MAIL $USER $SHELL $TERM 2C shell 특유의환경변수 $LOGNAME ( 셀소유자의사용자 id) Unix 시스템 8
6.4 연산식 C shell 의연산식 1 문자열연산식 2 산술연산식 3 화일지향적연산식 문자열연산식 연산자의미연산자의미 == 같으면참 =~ == 와동일. 단, 오른쪽에대표문자포함!= 같지않으면참!~!= 와동일. 단, 오른쪽에대표문자포함 Unix 시스템 9
6.4 연산식 ( 예 )% cat expr1.csh [ 교재 p251] echo -n "do you like C shell? set reply = $< if ($reply == "yes") then echo you entered yes else if ( $reply =~ y* ) then echo I assume you mean yes endif Unix 시스템 10
6.4 연산식 산술연산식 (C-like) 연산자의미연산자의미 -! unary 음수 논리적부정 <= >= < > 관계연산 ==!= 같다, 같지않다 * / % 곱셈, 나눗셈, 나머지 & ^ Bitwise and,xor,or + - 덧셈, 뺄셈 && logical and, or << >> Bitwise shift Unix 시스템 11
6.4 연산식 ( 예 ) % cat expr3.csh # set a = 3 set b = 5 if ($a > 2 && $b > 4) then echo expression evaluation seems to work endif Unix 시스템 12
6.4 연산식 연산식의결과를변수에할당하기위해서는 set 명령을사용하지않는다. ( 반드시공백으로분리 ) @ 모든셸변수들을표시 @ variable op expression 변수 variable 에 expression 의결과할당 @ variable[index] op expression variable 의 index 번째에할당 ( 예 ) % set a = 2 * 2 set: Syntax error. % @ a = 2 * 2 % echo $a 4 % @ a = $a + $a % @ b = ( $a && $flag ) && 때문에괄호필요 % set value = 1 % @ value ++ ++ 혹은 -- 연산가능 Unix 시스템 13
6.4 연산식 화일지향적연산식 -option "filename" 만일옵션이참이면 1 을, 아니면 0 을반환 만일 filename 이존재하지않으면 0 을반환 옵션의미옵션의미 r 셸은 filename 에대해읽기허가를갖는다. o 셸프로그램와 filename 의소유자가동일하다. w 셸은 filename 에대해쓰기허가를갖는다. z filename 이존재하고크기가 0 이다. x 셸은 filename 에대해실행허가를갖는다. f filename 은정규화일이다. e filename 이존재한다. d filename 은디렉토리이다. Unix 시스템 14
6.4 연산식 ( 예 ) % cat expr4.csh # echo -n "enter the name of the fiie you wish to erase: " set filename = $< if (! (-w "$filename") ) then echo you do not have permission to erase that file. else rm $filename echo file erased endif Unix 시스템 15
6.5 별명 (Aliases) 자신만의고유한명령어를만들어사용한다 alias [word [string] ] ( 예 )% alias 현재의별명들의목록을보여줌 ( 예 ) % alias word word가어떤string의별명인지를보여줌 ( 예 ) % alias dir 'ls -af % alias ls 'ls -af' ( 예 )% alias who 'date; who' who에대한무한루프발생 (error) % alias who 'date; /bin/who' who의절대경로사용해결 unalias pattern pattern과일치하는별명을제거한다. 만일 pattern에 * 가사용되면모든별명을제거한다. Unix 시스템 16
6.5 별명 (Aliases) 유용한별명 (.cshrc 에저장 ) % alias cd 'cd!*; set prompt="$cwd!>"; ls 지정된디렉토리로이동하고, prompt 를현재의디렉토리와마지막명령번호를포함하도록한후, 현재의목록을보여줌!* ( 두번째부터마지막번째까지의토큰즉모든인수들 )! ( 마지막명령어의번호 ) % alias ls 'ls -F' 화일과디렉토리에관한추가정보보이기 % alias rm 'rm -i' 지울지말지확인을먼저한다. % alias rm 'mv!* ~/tomb' 지울대상을 tomb 디레토리밑으로옮김 % alias h 'history' 히스토리정보얻기 % alias vi 'mesg n; /bin/vi!*; mesg y' vi 편집기간동안타인으로부터의메시지전달방해억제 % alias moer 'more' 일어나기쉬운오타방지 % alias ls-l 'ls -l' 일어나기쉬운오타방지 % alias ll 'ls -l 상세한목록정보얻기 Unix 시스템 17
6.6 히스토리 키보드로부터받은명령어들을순서대로기억해둠 번호가붙여진명령어 효과적인사용을위해, prompt 에명령어의번호가붙음 % set prompt =! % % echo hello 관련환경변수 $history 히스토리목록의크기, default = 1 $savehist 히스토리화일 ($HOME/.history) 에저장되는명령어의수 세션간에명령어접근을허용하는능력 (cf).history 화일은같은사용자에의하여생성된모든대화형 C shell 에의하여공유된다. ( 예 )$ % set history = 100 마지막 100 개의명령어를기억하도록함 ( 예 )$ % set savehist = 32 세션들사이에 32 개의명령어를저장함 Unix 시스템 18
6.6 히스토리 히스토리읽기 history [-rh] [number] 옵션이없으면마지막 $history 명령을나열한다 -r 히스토리의역순으로읽는다 -h 사건번호의표시를금지한다 number 읽을명령어의개수 ( 예 ) % history -r 3 마지막 3개의명령어를역순으로읽음 명령어의재실행 재실행된명령어텍스트는 echo된후실행된다 1!! 마지막명령의텍스트로치환된다 2!number 명시된사건번호를갖는명령의텍스트로치환된다 3!prefix prefix로시작되는마지막명령의텍스트로치환된다 4!?substring? substring을포함하는마지막명령의텍스트로치환 ( 예 ) %!41 41번째명령어를실행함 Unix 시스템 19
6.6 히스토리 히스토리수정자 (modifier) 사건명시자바로뒤에나와서이전명령의일부에접근 1 :0 첫번째토큰 2 :number (number+1) 번째토큰 3 :start-end (start+1) 부터 (end+1) 번째토큰 4 :^ 첫번째토큰 (: 은생략가능 ) 5 :$ 마지막번째토큰 (: 은생략가능 ) 6 :* 두번째부터마지막번째토큰 (: 은생략가능 ) ( 예 )48 % echo I like horseback riding I like horseback riding 49 %!!:0!!:1!!:2!!:4 echo I like riding I like riding 50 % echo!48:1-$ echo I like horseback riding I like horseback riding Unix 시스템 20
6.6 히스토리 화일수정자 기존의히스토리수정자에덧붙여화일이름의특정한부분을접근 함 1 :h 화일의바로앞부분 2 :r 화일의루트부분 3 :e 화일의확장자부분 4:t 화일의뒤부분 ( 예 ) 53 % ls /usr/include/stdio.h /usr/include/stdio.h 54 % echo!53:1:h /usr/inlcude 55 % echo!53:1:r /usr/inlcude/stdio 56 % echo!53:1:e h 57 % echo!53:1:t stdio.h 대치수정자 텍스트가대치된후재실행됨!event:s/pattern1/pattern2/ ( 예 )58 % ls /usr/include/stdio.h /usr/include/stdio.h 58 %!58:0!58:1:s/stdio/signal/ /usr/include/signal.h Unix 시스템 21
6.7 제어구조 C-like foreach-end 명령어목록이반복실행됨, 반복할때마다해당변수가다른값을가짐 foreach name ( wordlist ) commandlist end ( 예 )% cat foreach.csh # foreach color (red yellow green blue) echo one color is $color end % foreach.csh one color is red one color is yellow one color is green one color is blue Unix 시스템 22
6.7 제어구조 goto 무조건분기 label : goto label ( 예 ) % cat goto.csh # echo gotta jump! goto endofscript % goto.csh gotta jump! the end echo I'll never echo this endofscript: echo the end Unix 시스템 23
6.7 제어구조 if-then-else-endif if ( expr) command if ( expr1) then commandlist1 else if ( expr2 ) then commandlist2 else commandlist3 endif Unix 시스템 24
6.7 제어구조 ( 예 ) % cat if.csh # echo -n 'enter a number: ' # prompt user. set number = $< if ($number < 0) then echo negative else if ($number == 0) then echo zero else echo positive endif % if.csh enter a number: -1 negative Unix 시스템 25
6.7 제어구조 Onintr 키보드로부터 ^C (interrupt, SIGINT) 값을받았을때분기하도록지시 onintr [ - label ] - 인터럽트무시 label label로분기 ( 예 ) % cat onintr.csh # onintr controlc while (1) echo infinite loop sleep 2 end controlc: echo control C detected % onintr.csh infinite loop infinite loop ^C control C detected Unix 시스템 26
6.7 제어구조 repeat 단일명령어를지정된시간의수만큼반복수행한다 ( 예 ) % repeat 2 echo hi there 2 개의줄표시 while-end hi there hi there repeat expr command 참인동안명령어를반복수행함 while ( expr ) commandlist end (cf.) break continue Unix 시스템 27
6.7 제어구조 ( 예 ) % cat multi.csh # set x = 1 # set outer loop value while ($x <= &1) # outer loop set y = 1 # set inner loop value while ($y <= $1) # inner loop @ v = $x * $y # calculate entry echo -n $v " " # display entry @ y ++ # update inner loop counter end echo "" # newline @ x ++ # update outer loop counter end % multi.csh 7 1 2 3 4 5 6 7 2 4 6 8 10 12 14 3 6 9 12 15 18 21 4 8 12 16 20 24 28 5 10 15 20 25 30 35 6 12 18 24 30 36 42 7 14 21 28 35 42 49 Unix 시스템 28
6.7 제어구조 switch-case-endsw 다중분기지원 switch (expr) case pattern1 : commandlist1 breaksw case pattern2 : case pattern3 : commandlist2 breaksw default : commandlist2 endsw Unix 시스템 29
6.7 제어구조 ( 예 ) cat menu.csh # echo menu test program set stop=0 while ( $stop == 0 ) cat << ENDOFMENU 1 : print the date. 2, 3 : print the current working directory 4 : exit ENDOFMENU echo echo -n 'your choice? ' set reply = $< echo "" switch ($reply) case "1": date breaksw case "2": case "3": pwd breaksw case "4": set stop = 1 breaksw default: echo illegal choice breaksw endsw end Unix 시스템 30
6.7 제어구조 예제 : JUNK junk -lp {filename}* 지정된화일을지우는 rm 대신사용하는명령으로, 화일을지우지않고 $HOME/.junk에이동시킨다. -l $HOME/.junk의내용을보여준다 (list). -p $HOME/.junk을제거한다 (purge). 만일.junk 디렉토리가없으면자동으로생성해준다. Unix 시스템 31
6.7 제어구조 ( 예 ) % cat junk.csh #! /bin/csh # junk script # author: Graham Glass # # Initialize variables # set filelist = () set listflag = 0 set purgeflag = 0 set fileflag = 0 set junk = ~/.junk # # Parse command line # foreach arg ($*) switch ($arg) case "-p": set purgeflag = 1 breaksw case "-l": set listflag = 1 breaksw case -*: each $arg is an illegal option goto error breaksw default: set fileflag = 1 set filelist = ($filelist $arg) breaksw endsw end # # Check for too many options # @ total = $listflag + $purgeflag + $fileflag if ($total!= 1) goto error # # If junk directory doesn't exist, create it # if (!(-e $junk)) then 'mkdir' $junk endif Unix 시스템 32
6.7 제어구조 # # Process options # if ($listflag) then 'ls' -lgf $junk exit 0 endif # if ($purgeflag) then 'rm' $junk/* exit 0 endif # if ($fileflag) then 'mv' $filelist $junk exit 0 endif # exit 0 # # Display error message and quit # error: cat << ENDOFTEXT Dear $USER, the usage of junk is as follows: junk -p means "purge all files" junk -l means "list junked files" junk <list of files> to junk them ENDOFTEXT exit 1 Unix 시스템 33
6.9 개선점 명령어재실행을위한최적방법 ^ pattern1^pattern2 메타문자 { } ( 예 ) % cc fil.txt Can't open file fil.txt % ^fil^file cc file.txt a{b,c}d abd acd( 접두사, 접미사의입력시간감소 ) ( 예 ) % cp /usr/include/{stdio,signal}.h. 두파일을복사 화일이름대치 1 화일이름대치금지 : 변수 $noglob 설정 (default: 비설정 ) 2 패턴불일치시에러보고금지 : 변수 $nonomatch 설정 (default: 비설정 ) Refer to set, unset Unix 시스템 34
6.9 개선점 ( 예 ) % echo p* prog1.cprog2.c % set noglob 대표문자처리금지 % echo p* P* ( 예 ) % echo *a echo: No match. % set nonomatch 에러발생하지않고원래패턴인쇄 % echo *a *a Unix 시스템 35
6.9 개선점 redirection 1 표준에러채널을리다이렉션 : >& 또는 >>& 2 예상외의덮어씌우기로부터화일보호 : $noclobber 설정 (default: 비설정 ) ( 예 ) % (process1 > file1) >& file2 표준출력은 file1 으로표준에러는 file2 로저장함 ( 예 ) % set noclobber % cc a.c >& errors errors: File exists. 표준출력뿐아니라표준에러도 pipe 시킴 & ( 예 ) % cc a.c & more ( 예 )% (cc a.c > file1) & more cc a.c 의표준출력은 file1 으로저장하고, 명령어그룹의출력과에러채널을 more 로파이프처리함 Unix 시스템 36
6.9 개선점 작업제어를위한추가적내장명령어제공 1 stop {%job}* 지정된작업을중단한다. [ 교재 p216] %integer 작업번호가 integer인작업 %prefix prefix로이름이시작하는작업 %+ 마지막으로참조된작업 (default) %% %+ 와동일 %- 마지막에서두번째로참조된작업 ( 예 ) % stop %man % stop %1 2suspend su나 script 등으로불러들인 shell을중단시킴 Unix 시스템 37
6.9 개선점 3 nice [+/- number] [command]] command의우선순위를 number로설정한다. ( 적당한때수행 ) 우선순위 number가높을수록실행은더늦다. 슈퍼유저만이음수의우선순위를설정할수있다. 우선순위가생략되면 4로간주한다. command가명시되지않으면현재의 shell에대한것으로간주 4nohupcommand command를수행하고모든방해조건으로부터보호한다 command가명시되어있지않으면해당셀의모든명령어가됨 backgounding command도해당됨에주의 (C 셸에서는 default) 5 notify {%job}* 지정된작업이상태를바꿀때즉시통보하도록한다. 모든작업에대해서할때는, $notify를설정한다. Unix 시스템 38
6.9 개선점 6 로그인셀의다양한종료방법 logout : login shell만을종료 exit : login shell 및 interactive shell의종료 control-d : 입력종료 ($ignoreeof이설정되면무력해짐 ) ( 예 ) % set ignoreeof % ^D use "logout" to logout % logout C shell 종료시에, 2개의끝내기화일을탐색 $HOME/.logout /etc/.logout (cf.) 끝내기화일의주요내용임시디렉토리지우기, 종료메시지등 Unix 시스템 39
6.10 추가내장명령어 chdir [path] cd와동일 glob {arg} cho와비슷하나, 마지막출력에공백대신널 (ASCII 0) 로 arg 목록을구분하는것이 echo와다름 source [-h] filename 스크립트가실행될대서브셀로번역된다. 따라서원래의셀에는아무런영향을미치지못한다. 스크립트를현재의셀에의해번역실행하여영향을주고자할때이 source를사용한다. -h 스크립트 filename 안에있는명령어들이단지히스토리리스트에놓임 filename 스크립트수행시발생한에러는원래의셀로반환된다 ( 예 )% source.login.login화일을재실행 ( 서브셀을부르지않음 ) Unix 시스템 40
6.11 디렉토리스택 pushd [ +number name ] 명시된디렉토리를디렉토리스택에추가시킴 1 name이주어지면, 현재작업디렉토리는스택에삽입되고, 셀은주어진이름의디렉토리로옮겨간다 2 -number가주어지면, 스택의 number번째원소는스택의탑으로옮겨지고현재의작업디렉토리가된다. 스택의원소는탑을 0으로하여오름차순으로번호가메겨져있다. 3 인수가주어지지않으면, 스택탑의두원소는자리바꿈을한다 popd [ +number ] 명시된디렉토리를디렉토리스택에삭제하고, 1 -number가주어지면, 셀은스택의 number번째디렉토리로옮겨간다 2 인수가주어지지않으면, 셀은스택탑의디렉토리로옮겨가고그디 렉토리를스택에서삭제한다. Unix 시스템 41
6.11 디렉토리스택 dirs 현재디렉토리스택의내용을보여준다 ( 예 ) % pwd /usr/mysung % pushd / / ~ % pushd /usr/inlude /usr/include / ~ % pushd / /usr/include ~ % popd /usr/inlude ~ hash table C shell은해시테이블이라는내부적자료구조를유지하여실행화일탐색을빠르게함 1 $PATH가바뀔때마다 2 새로운실행화일이 $PATH 안의어떤디렉토리에해시테이블을다시작성한다. ( 예 ) % rehash 해시테이블을다시작성 ( 예 )% hashstat 해시통계자료표시 Unix 시스템 42
6.12 명령줄옵션 만일명령줄의첫째인수가 - 라면, C shell 은 login shell 로시작된다. 여기에추가로 C shell 은다음의명령줄옵션을지원한다. 옵션의미옵션의미 -c string string 명령을실행하기위하여셀을생성한다. -t 표준입력으로부터한줄을읽고실행한다. -e 어떤명령어가 0 이아닌종료코드를반환하면, 셀은종료된다. -v $verbose 를설정하게한다. -f 셀은시작하지만,.cshrc 에서명령을읽지는않는다. -V.cshrc 이실행되기전에 $verbose 를설정하는것을제외하고는 -v 와같다. Unix 시스템 43
6.12 명령줄옵션 옵션의미옵션의미 -i 대화형셀을형성한다. 즉, SIGTERM, SIGINT, SIGQUIT 메시지를모두무시하는것을제외하고는 -s 와같다. -x $echo 를설정하게한다. -n 명령을문법적으로분석하지만, 실행하지는않는다. 단지디버깅을위한것임 -X.cshrc 가읽혀지기전에 $echo 를설정하는것을제외하고는 -x 와같다. -s 표준입력으로부터명령을읽고셀메시지를표준에러채널에보내는셀을생성한다. filename 만일 -c, -i, -s, -t 옵션이사용되지않으면 filename 에있는셀명령어들을실행한다. filename 스크립트내에서 fulename 은 $0 이다. Unix 시스템 44
과제 4 10 월 31 일 ( 금 ) 까지 1. 교재 p 284 연습문제 1. track C shell version 2. C 셸버전으로 문제 [ 자료 p40-42] 문제1. watchfor 문제2. pick 문제3. checkmail 과제제출방법 1. Electrical Version : csmail.inchon.ac.kr (211.119.245.75) 의 /home/mysung/2003unixlinux/classa ( 또는 classb) 에자신의학번으로디렉토리만들고그안에복사 2. Paper Version : 종이에소스와실행과정및결과출력하여제출 Unix 시스템 45
C 셸버전 1 문제 1: 다음은 60 초마다한번씩 mary 가로그인했는지조사하는본셸프로그램 watchfor 이다. 이프로그램을참조하여매개변수로입력된사람이로그인했는지조사하는 C 셸버전을작성하되, 한사람이상도한번에조사할수있도록하라. (p157 egrep 참조 ) $ cat watchfor PATH=/bin:/usr/bin until who grep mary do sleep 60 done Unix 시스템 46
C 셸버전 2 문제 2: 다음의 pick 은매개변수로입력된인수들을취사선택하는본쉘프로그램이다. 이프로그램을코딩하여실행해보고, 명령줄에아무것도없으면표준입력으로부터인수를읽는 pick 의 C 셸버전을작성하라. 빈칸을적절히다루고, q 도잘동작하도록하라. $ cat pick PATH=/bin:/usr/bin for i do echo $i? c read response case $response in y*) echo $i ;; q*) break esac done Unix 시스템 47
C 셸버전 3 문제 3 : 다음의 checkmail 본쉘프로그램을코딩하여실행해보고 C 셸버전으로수정하되메시지에메일을보낸사람의이름이나타나도록하고우편함파일 (MAIL) 이존재하지않더라도잘동작하도록하라. $ cat checkmail PATH=/bin:/usr/bin MAIL=/var/mail/`logname` t=${t-60} x= `ls -l $MAIL` while : do y= `ls -l $MAIL` echo $x $y x = $y sleep $t done awk $5 < $14 {print You have mail } Unix 시스템 48