480 likes | 755 Views
6 장 . C 셸. 컴퓨터공학과 강성인. 6.1 소개. C Shell 의 추가된 기능들 변수를 설정하고 접근하는 여러 가지 방법 조건 분기, 루프, 인터럽트 조작을 지원하는 내장 프로그래밍 언어 별명 (alias) 을 사용한 주문화된 고유명령어 히스토리 메카니즘을 이용한 그 이전 명령어로의 접근 개선된 작업 제어 새로운 내장 명령어와 기존 명령어의 개선. 6.2 시작하기. /bin/csh 시작순서 ① $HOME/.cshrc ( 새로운 C shell 이 실행될 때 마다 )
E N D
6장. C 셸 컴퓨터공학과 강성인
6.1 소개 • C Shell의 추가된 기능들 • 변수를 설정하고 접근하는 여러 가지 방법 • 조건 분기, 루프, 인터럽트 조작을 지원하는 내장 프로그래밍 언어 • 별명(alias)을 사용한 주문화된 고유명령어 • 히스토리 메카니즘을 이용한 그 이전 명령어로의 접근 • 개선된 작업 제어 • 새로운 내장 명령어와 기존 명령어의 개선
6.2 시작하기 • /bin/csh • 시작순서 • ① $HOME/.cshrc (새로운 C shell이 실행될 때 마다) • ② /etc/.login (로그인할 때만) • ③ $HOME/.login (로그인할 때만) • .cshrc 파일: 자주 쓰이는 별명을 설정함 • .login 파일: $TERM, $PROMPT, $PATH 등의 변수 값을 설정함
80 /home2/stud/04/sikang >cat .cshrc # @(#)cshrc 1.11 89/11/29 SMI umask 022 set path=(/bin /usr/bin /usr/ucb /etc .) if ( $?prompt ) then set prompt="\! $cwd >" set history=32 set savehist=5 set noclobber filec set ignoreeof alias cd 'cd \!*;set prompt="\! $cwd >"; ls -F' alias ls ls -F alias rm rm -i alias h history alias ll ls -l endif
6.3 변수 • 단순 변수의 생성과할당 및 변수 해제 • set {name [= word]}* • unset {name}* % set : 모든 지역 변수의 리스트가 나타남 % set name = Graham Glass % set name = “Graham Glass" % echo $name • 단순 변수로의 접근 • ${name} : 변수 name의 값 (접속 사용할 때) • ${?name} : 변수 name의 설정되어 있으면 1, 아니면 0의 값
% 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}* ) }* • 리스트 변수로의 접근 • $name[selector] : 리스트 변수 name의 값(독립 사용할 때) • ${name[selector]} : 리스트 변수 name의 값(접속 사용할 때) • $#name : 리스트 변수 name의 원소들의 개수(독립 사용할 때) • ${#name} : 리스트 변수 name의 원소들의 개수(접속 사용할 때) ※ selector : [start-end]형태, start가 명시 안되면 1로 간주, end가 생략되면 마지막 원소의 인덱스로 간주 *는 모든 범위 • 리스트 변수의 추가 • 원래의 리스트에 원소를 더하고, 이들을 괄호로 묶어 원래 변수로 치환
% set colors = ( red yellow green ) % echo $colors red yellow green %set colors = ( red yellow green ) %set colors[4] = pink Subscript out of range %set colors = ( $colors blue ) %echo $colors red yellow green blue % 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
미리 정의된 여러 지역/환경 변수들(P.253 표 참조) %cat var5.csh # echo -n "please enter your name: " set name = $< #input string echo hi $name, your current directory is $cwd %var5.csh please enter your name: ksi hi ksi, your current directory is /home/sikang
환경 변수의 값 할당 및 해제 • setenv name word • unsetenv name (ex)%setenv TERM vt100 % echo $TERM • 미리 정의된 환경 변수 • 공통적으로 미리 정의된 환경 변수 $HOME $PATH $MAIL $USER $SHELL $TERM • C shell 특유의 환경 변수 $LOGNAME (셸 소유자의 사용자 id)
연산자 의 미 연산자 의 미 ==와 동일. 단, 오른쪽에 대표문자 포함 같으면 참 == =~ !=와 동일. 단, 오른쪽에 대표문자 포함 != 같지 않으면 참 !~ 6.4 연산식 • 문자열 연산식 % cat expr1.csh 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 % expr1.csh do you like the C shell? yeah I assume you mean yes
산술 연산식 • 산술 연산식을 계산할 때 널 문자열은 0과 동일하게 취급 • &, &&, ||, |, <, >, >>, << 연산자들은 셸이 특별하게 번역하는 것을 막기 위해 괄호로 묶어야 한다. • 연산식의 결과를 변수에 할당하기 위해서는 set 명령을 사용하지 않고 내장 명령어 “@”를 사용. ※ @ 이후의 연산식은 반드시 공백으로 분리 @: 모든 셸 변수들을 표시 @ variable op expression : variable에 expression의 결과 할당 @ variable[index] op expression : variable의 index 번째에 할당 op : =, +=, -=, *=, /=, ++, -- 연산자 사용 가능
연산자 의 미 연산자 의 미 - unary 음수 <= >= < > 관계 연산 논리적부정 == != 같다, 같지 않다 ! 곱셈,나눗셈,나머지 & ^ | Bitwise and,xor,or * / % logical and, or 덧셈, 뺄셈 && || + - Bitwise shift << >>
% cat expr3.csh # set a = 3 set b = 5 if ($a > 2 && $b > 4) then echo expression evaluation seems to work endif % expr3.csh echo expression evaluation seems to work % set a = 2 * 2 set: Syntax error. % @ a = 2 * 2 ; 반드시 공백 분리 % echo $a 4 % @ a = $a + $a % set flag = 1 % @ b = ( $a && $flag ) ; && 때문에 괄호 필요 % echo $b 1 % @ flag++ : ++ 혹은 -- 연산 가능 % echo $flag 2
옵 션 의 미 옵 션 의 미 셸은 fileName에 대해 읽기 허가를 갖는다. 셸 프로그램와 fileName의 소유자가 동일하다. o r 셸은 fileName에 대해 쓰기 허가를 갖는다. fileName이 존재하고 크기 가 0이다. z w 셸은 fileName에 대해 실행 허가를 갖는다. f fileName은 정규파일이다. x fileName이 존재한다. d fileName은 디렉토리이다. e 6.4 연산식 • 파일 지향 연산식 -option "fileName" • 만일 옵션이 참이면 1을, 아니면 0을 반환 • 만일 fileName이 존재하지 않거나 접근할수 없으면 0을 반환
% 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 % expr4.csh enter the name of the fiie you wish to erase: / you do not have permission to erase that file.
6.5 파일 이름 완성 • 명령줄에 긴 파일 이름을 입력하는 것을 피할 수 있다. • set filec • filec 변수를 먼저 설정한다. • 파일 이름의 일부를 입력하고 ESC 누름 • 유일한 파일식별가능 : 나머지 자동추가 • 식별불가능 : 입력한 내용 아무 변화 없음 120 /home/sikang >ls -al .log* ; 유일한 파일 -rw-r--r-- 1 sikang 2008 623 4월 28일 22:32 .login 121 /home/sikang >ls -al .login ; .l을 추가한후 ESC 키 입력 -rw-r--r-- 1 sikang 2008 623 4월 28일 22:32 .login
6.6 별명(Aliases) • 자신만의 고유한 명령어를 만들어 사용한다 alias [word [string] ] • unalias pattern • pattern과 일치하는 별명을 제거한다. • 만일 pattern에 *가 사용되면 모든 별명을 제거한다. • 유용한 별명(P.262) • % alias cd 'cd \!*; set prompt="$cwd \!>"; ls' 지정된 디렉토리로 이동하고, prompt를 현재의 디렉토리와 마지막 명령 번호를 포함하도록 한 후, 현재의 목록을 보여줌 \!* (두 번째부터 마지막번째까지의 토큰 즉 모든 인수들) \! (마지막 명령어의 번호)
6.7 히스토리 • 키보드로부터 받은 명령어의 기록을 보존 • 번호가 붙여진 명령어 효과적인 사용을 위해, prompt에 명령어의 번호가 붙음 % set prompt = “\! $cwd >” 1 /home/sikang >_ • 관련환경 변수 • $history : 히스토리 목록의 크기, default = 1 • $savehist • 히스토리 파일($HOME/.history) 에 저장되는 명령 어의 수 • 세션 간에 명령어 접근을 허용하는 능력 • .history 파일은 같은 사용자에 의하여 생성된 모든 대화형 C shell에 의하여 공유된다. % set history = 100 마지막 100개의 명령어를 기억하도록 함 % set savehist = 32 세션들 사이에 32개의 명령어를 저장함
히스토리 읽기 • history [-rh] [number] 옵션이 없으면 마지막 $history 명령을 나열한다 -r 히스토리의 역순으로 읽는다 -h 사건 번호의 표시를 금지한다 number 읽을 명령어의 개수 • 명령어의 재실행 • 재실행된 명령어 텍스트는 echo된 후 실행된다 • !! : 마지막 명령의 텍스트로 치환된다 • !number : 명시된 사건 번호를 갖는 명령의 텍스트로 치환된다 • !prefix : prefix로 시작되는 마지막 명령의 텍스트로 치환된다 • !?substring? : substring을 포함하는 마지막 명령의 텍스트로 치환 (예) % !41 41번째 명령어를 실행함
히스토리 수정자(modifier) 사건 명시자 바로 뒤에 나와서 이전 명령의 일부에 접근 • :0 : 첫 번째 토큰 • :number : (number+1)번째 토큰 • :start-end : (start+1)부터 (end+1)번째 토큰 • :^ : 두 번째 토큰 (:은 생략 가능) • :$ : 마지막 번째 토큰 (:은 생략 가능) • :* : 두 번째부터 마지막번째 토큰 (:은 생략 가능)
6 /home/sikang >echo I like horseback riding I like horseback riding 7 /home/sikang >!!:0 !!:1 !!:2 !!:4 ; 지정된 인수로 접근 echo I like riding I like riding 8 /home/sikang >echo !6:1-$ ; 인수의 범위로 접근 echo I like horseback riding I like horseback riding 9 /home/sikang >echo !6* ; 인수의 두 번째 토큰부터 마지막 토큰 echo I like horseback riding I like horseback riding 10 /home/sikang >
파일 수정자 • 기존의 히스토리 수정자에 덧붙여 파일 이름의 특정한 부분을 접근함 • :h 파일의 바로 앞 부분 • :r 파일의 루트 부분 • :e 파일의 확장자 부분 • :t 파일의 뒤 부분 • 대치 수정자 • 텍스트가 대치된 후 재실행됨 !event:s/pattern1/pattern2/
11 /home/sikang >ls /usr/include/stdio.h /usr/include/stdio.h 12 /homesikang >echo !11:1:h ; 파일의 바로 앞 부분 echo /usr/include /usr/include 13 /home/sikang >echo !11:1:r ; 파일의 루트 부분 echo /usr/include/stdio /usr/include/stdio 14 /home/sikang >echo !11:1:e ; 파일의 확장자 부분 echo h h 15 /home/sikang >echo !11:1:t ; 파일의 뒤 부분 echo stdio.h stdio.h 16 /home/sikang >echo !11:1:s/stdio/signal/ ; 대치수행 echo /usr/include/signal.h /usr/include/signal.h 17 /home/sikang >
foreach name ( wordlist ) commandlist end 6.8 제어구조 • foreach-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
goto label ……… label : • goto • 무조건 분기 % cat goto # echo gotta jump! goto endOFScript echo I'll never echo this endOFScript: echo the end • % goto.csh • gotta jump! • the end
if ( expr) command • if-then-else-endif if ( expr1) then commandlist1 else if ( expr2 ) then commandlist2 else commandlist3 endif
% 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
onintr [ - | label ] - 인터럽트 무시 label: label로 분기 • Onintr • 키보드로부터 ^C (interrupt, SIGINT)값을 받았을 때 분기하도록 지시 % 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
repeat expr command while ( expr ) commandlist end (cf.) break continue • repeat • 단일 명령어를 지정된 시간의 수만큼 반복 수행한다 • while-end • 참인 동안 명령어를 반복 수행함 % repeat 2 echo hi there 2개의 줄 표시 hi there hi there
% 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
switch (expr) case pattern1 : commandlist1 breaksw case pattern2 : case pattern3 : commandlist2 breaksw default : commandlist2 endsw • switch-case-endsw • 다중 분기 지원
6.9 개선점 • 명령어 재실행 • ^ pattern1^pattern2 (이전 명령어에만 적용) • 메타문자 { } • a{b,c}d → abd acd(접두사, 접미사의 입력시간 감소) (ex)% cp /usr/include/{stdio,signal}.h . → 두 파일을 복사 18 /home/sikang >ls -l .cshr .cshr: 해당 파일이나 디렉토리가 없음 19 /home/sikang >^.cshr^.cshrc ls -l .cshrc -rw-r--r-- 1 sikang 2008 345 4월 28일 09:45 .cshrc
파일 이름 대치 • 파일 이름 대치 금지: 변수 $noglob 설정(default: 비설정) • 패턴 불일치시 에러 보고 금지: 변수 $nonomatch 설정 (default: 비설정)→ Refer to ‘set’, ‘unset’ • % echo p* • prog1.c prog2.c • % set noglob : 대표문자 처리 금지 • % echo p* • p* • % unset noglob • % echo *a • echo: No match. • % set nonomatch : 에러 발생하지 않고 원래 패턴 인쇄 • % echo *a • *a
리다이렉션 • 표준 에러 채널을 리다이렉션 : >&또는 >>& • 의도하지 않은 덮어씌우기로부터 파일 보호 : $noclobber 설정 (default: 비설정) /home/sikang >lls >& error /home/sikang >cat error lls: 명령어가 없음 /home/sikang >set noclobber /home/sikang >cp >& error error: 파일 있음
표준출력 뿐 아니라 표준에러도 pipe시킴 • |& (예) % cc a.c |& more (예)% (cc a.c > file1) |& more cc a.c의 표준 출력은 file1으로 저장하고, 명령어 그룹의 출력과 에러 채널을 more로 파이프 처리함 /home/sikang >lls | wc -w lls: 명령어가 없음 0 /home/sikang >lls |& wc -w 3
jobs [-l] • 모든 셸 작업 목록을 화면에 표시 • -l 옵션을 사용하면 프로세스 ID 가 리스트에 추가 • 출력구문의 형식 job# [ +/- ] PID Status Command • +는 후면에 위치한 마지막 작업 의미 • -는 마지막에서 두 번째 작업 의미 • status는 다음중의 하나이다.
/home/sikang >sleep 30& [1] 4177 /home/sikang >sleep 30& [2] 4178 /home/sikang >jobs [1] - Running sleep 30 [2] + Running sleep 30 /home/sikang >jobs -l [1] - 4177 Running sleep 30 [2] + 4178 Running sleep 30
작업 명시 : bg, fg, kill 명령은 다음 형식 중 하나를 사용하여 job을 명시할 수 있게 한다.
bg [ %job] • 명시된 작업을 후면 프로세서로 다시 시작 • 명시된 작업이 없으면 마지막 참조된 작업 다시 시작 /home/sikang >sleep 100 : 전면 작업 시작 ^Z : 일지 중단 중단됨 (사용자) [2] Done sleep 30 [1] - Done sleep 30 /home/sikang >bg %+ : 마지막으로 참조된 작업을 후면 프로세스로 다시 시작 [3] + sleep 100 & /home/sikang >jobs [3] + Running sleep 100
fg [ %job] • 명시된 작업을 전면 프로세서로 다시 시작 • 명시된 작업이 없으면 마지막 참조된 작업 다시 시작 /home/sikang >sleep 1000& : 후면 프로세스 시작 [4] 4193 [3] Done sleep 100 /home/sikang >fg %sl : “sl”로 시작하는 명령어 전면에서 다시 시작 sleep 1000
stop {%job}* • 지정된 작업을 중단한다. /home/sikang >sleep 100& [1] 4237 /home/sikang >stop %1 [1] + 중단됨 (신호) sleep 100 /home/sikang >jobs -l [1] + 4237 중단됨 (신호) sleep 100 /home/sikang >kill 4237 /home/sikang >jobs -l [1] 4237 종료됨(Terminated) sleep 100
6.10 추가 내장 명령어 source [-h] fileName • 스크립트를 현재의 셸에 의해 번역 실행하여 영향을 주고자 할 때 사용한다.(Korn 셸의 도트명령(.)과 같은 기능) (예)% source .login → .login파일을 재실행 (서브셸을 부르지않음)
6.11 디렉토리 스택 pushd [ +number | name ] • 명시된 디렉토리를 디렉토리 스택에 추가시킴 • name이 주어지면, 현재 작업 디렉토리는 스택에 삽입되고, 셸은 주어진 이름의 디렉토리로 옮겨간다 • number가 주어지면, 스택의 number번째 원소는 스택의 탑으로 옮겨지고 현재의 작업 디렉토리가 된다. 스택의 원소는 탑을 0으로하여 오름차순으로 번호가 메겨져 있다. • 인수가 주어지지 않으면, 스택 탑의 두 원소는 자리바꿈을 한다
popd [ +number ] • 명시된 디렉토리를 디렉토리 스택에 삭제한다. • number가 주어지면, 셸은 스택의 number번째 디렉토리를 디렉토리 스택에서 삭제한다. • 인수가 주어지지 않으면, 셸은 스택 탑의 디렉토리로 옮겨가고 그 디렉토리를 스택에서 삭제한다. • 현재 디렉토리 스택의 내용을 보여 준다 dirs
%cd / %dirs : 현재 디렉토리 스택의 내용을 표시 / %pushd ~ : 홈디렉토리를 디렉토리 스택에 추가 ~ / %pwd : 현재 디렉토리가 홈디렉토리로 변경 /home/sikang %pushd /etc : /etc를 디렉토리 스택에 추가 /etc ~ / %pushd +2 : 디렉토리 스택의 2번째 원소인 “/”를 스택의 / /etc ~ 탑으로 이동 하고 현재 작업 디렉토리로 변경 %pushd : 디렉토리 스택의 0번째와 1번째 원소가 자리 바꿈 /etc / ~ %popd +2 : 2번째 원소를 디렉토리 스택에서 삭제 /etc / %popd : 스택의 탑에 있는 원소를 스택에서 삭제 / %popd popd: 디렉토리 스택이 비어 있음
hash table • C shell은 해시 테이블이라는 내부적 자료 구조를 유지하여 실행파일 탐색을 빠르게 함 • $PATH가 바뀔 때마다 • 새로운 실행파일이 $PATH 안의 어떤 디렉토리에 해시 테이블을 다시 작성한다. • 해시 테이블은 .cshrc파일이 읽혀질 때 마다 자동적으로 작성되고 rehash명령을 사용하면 다시 작성된다. • hashstat명령은 해시 통계 자료 표시