Chapter 10 The Bourne Shell
Shell Program between User & OS Korn Shell C Shell Bourne Shell Bash Shell POSIX Shell Korn Shell C Shell Korn Shell C Shell Bourne Shell POSIX Shell Bash Shell
Bourne shell 도구 프로그램 (utility) 명령어 해석기 (command interpreter) 프로그래밍 언어 사용자 입력 명령어의 실행 프로그래밍 언어 shell script에 있는 명령을 실행
쉘 스크립트의 작성 및 실행 쉘 스크립트는 쉘에 의해 수행될 명령어를 담은 파일 편집기로 쉘 스크립트 작성 $ vi whoson 쉘 스크립트에 대해 실행모드 허락 $ chmod u+x whoson 스크립트의 이름을 호출하여 실행 $ whoson 또는 $ . /whoson, $ sh whoson date echo Users Currently Logged In who
명령어의 분리 및 묶음 <newline> 과 ; \ 세미콜론(;)을 사용함으로써 한 명령줄에 있는 일련의 명령어들을 분리할 수 있다. 그러나 <return>이 입력된 후에야 실행됨 $ a; b; c <return> \ 명령어가 한 줄을 넘어 다음줄에 연속될 때 사용
| 와 & $ a | b | c $ a & b & c $ a & b & c & $ a | b | c & $ (a ; b) & (c ; d) &
표준에러의 재지정 $ cat x y 1> hold1 2> hold2 $ cat hold1 This is y cat: cannot open x $ cat x y 1> hold 2>&1 표준 출력은 hold, file descriptor 2는 file descriptor 1의 사본 즉, 표준출력과 표준에러는 hold
프로세스 fork 프로세스의 구조 새로운 프로세스를 생성하는 운영체제 루틴의 이름 부모 프로세스는 자식 프로세스를 fork(spawn) 한다. 프로세스의 구조 프로세스는 명령어의 수행으로서 파일시스템처럼 계층적 구조를 갖는다. root process는 사용자가 작업하는 모든 프로세스의 조상 getty login shell
프로세스 명령어의 실행 프로세스 ID parent process P forks a child process C P sleeps waiting to wake up C finishes execution and dies P wakes up and prompts for another command 프로세스 ID 각 프로세스의 시작마다 고유의 프로세스 번호 소유 자식 프로세스는 부모 프로세스와 다른 번호 소유 $ ps -l
변수 (variables) User-created variables Keyword shell variables Readonly shell variables
User-created variables $ person=alex ; no space before and after = $ echo person ; copy arguments to standard out person $ echo $person ; substitute the value of the variable alex $ echo “$person”
User-created Variables $ echo ‘$person’ ; prevent variable substitution $person $ echo \$person $ person= ; 변수의 값을 삭제 $ unset person $ readonly person ; 변수의 값 변경 불능 $ readonly ; 사용자 정의 readonly 변수 나열
export 명령어 export는 child 프로세스가 parent 프로세스의 변수를 접근할 수 있도록 하는 명령어 ( 일반적으로 변수는 그 변수가 선언된 프로세스에서만 접근 가능하다.) 파일 extest1 cheese=american echo “extest1: $cheese” subtest echo “extest1 2: $cheese”
export 명령어 파일 subtest % extest1 extest1 1: american subtest 1: echo “subtest 1: $cheese” cheese=swiss echo “subtest 2: $cheese” % extest1 extest1 1: american subtest 1: subtest 2: swiss extest1 2: american
export 명령어 파일 extest2 $ extest2 extest2 1: american export cheese cheese=american echo “extest2 1: $cheese” subtest echo “extest2 2: $cheese” $ extest2 extest2 1: american subtest 1: american subtest 2: swiss extest2 2: american
read 명령어 파일 read1 $ read1 Go ahead: This is a line. echo “Go ahead: \c” ; suppress newline read firstline echo “You entered: $firstline” $ read1 Go ahead: This is a line. You entered: This is a line.
명령어의 대치 $ cat dir2 echo You are using the `pwd` directory. $ dir2 You are using the /home/jenny directory.
Keyword Shell Variables HOME, PATH, MAIL, MAILPATH, MAILCHECK, PS1, PS2, IFS, CDPATH, TZ $ echo $HOME $ PATH=/usr/ucb:/usr/bin:/usr/sbin:/home/jenny/bin: $ export PATH $ echo $MAIL /var/mail/jenny (또는 /var/spool/mail/jenny) $ PS1=“`hostname` : “ bravo: echo test test bravo:
. command .(dot) command $ . .profile $ . ./.profile runs the script as a part of the current process. $ . .profile $ . ./.profile 다시 로그인 하지 않아도 .profile의 변경내용이 즉시 효과가 있도록 함
Readonly Shell Variables $0 호출한 프로그램 이름 $1, $2, … , $9 인수 $* 모든 인수 지정 (“arg1 arg2 arg3…”) $@ 모든 인수 지정(“arg1” “arg2” … ) $# 인수의 개수 $$ 수행중인 쉘의 PID $! background에서 수행한 지난번 프로세스의 PID $? 지난번 프로세스의 exit 상태 0 true, 성공적 수행 nonzero false, 명령어 수행 실패
shift and set shift set promotes each of the command line arguments $ shift ; arg1 arg2, arg2 arg3, … set command line arguments를 변수에 할당 $ cat set_it set this is it echo $3 $2 $1 $ set_it it is this
흐름제어 명령어 if <test-com> then <coms> fi echo Usage: chkargs argument, … 1 >&2 exit 1 fi echo Program running exit 0 if <test-com> then <coms> else <coms> fi if <test-com> then elif <test-com> then <coms> else <coms> fi
흐름제어 명령어 for <loop-index> in <arg-list> do <coms> done for fruit in apples oranges pears bananas do echo $fruit done echo Task complete. break done문 다음으로 이동하여 loop로부터 탈출 continue done문으로 이동하여 loop를 계속 수행
흐름제어 명령어 while <test-com> do <coms> done number=0 while [ “$number” -lt 10 ] do echo “$number\c” number = `expr $number + 1` done echo
흐름제어 명령어 until <test-com> do <coms> done case <test-string> in pattern-1) coms-1 ;; pattern-2) coms-2 esac
Here document 쉘 스크립트 자체로부터 입력을 받아들임 파일 birthday $ birthday Jenny grep -i “$1” <<+ Alex June 22 Barbara February 3 Jenny January 23 Nancy June 26 $ birthday Jenny
exec 쉘에 내장된 프로그램 exec와 . 의 차이점 새로운 프로세스를 생성하지 않고 명령어를 실행 exec date 쉘 스크립트 내에서 스크립트의 입출력을 재지정할 때 사용 exec < infile exec > outfile 2> errfile exec와 . 의 차이점 . 은 스크립트만을 실행하나 exec은 스크립트와 컴파일된 프로그램을 모두 실행. 실행 후 . 은 제어를 원래 스크립트에게 되돌려 주나, exec은 그렇지 않다. 새로운 프로세스를 생성하지 않으므로 exec은 실행속도가 빠르다.
trap 스크립트가 interrupt, illegal instruction, bad system call 등의 시그널을 받았을 때 취할 행동을 지정 1 hang up 2 terminal interrupt (DEL or ^C) 3 quit (^l or ^\) 9 kill (kill -9) 15 kill (software termination) 18 stop (^Z) trap ‘echo PROGRAM INTERRUPTED; exit 1’ 2 trap ‘exit 1’ 1 2 3 15 trap ‘rm /tmp/$$.$script 2> /dev/null’ 0
쉘 함수 (Shell Function) 쉘 함수는 쉘 스크립트처럼 일련의 명령어를 저장하지만, 파일이 아니라 주기억장치에 저장한다. 빨리 수행됨. 쉘 함수는 호출한 쉘과 같은 쉘에서 수행됨 go() { cd $1 PS1=“[ `pwd` ] “ } $ pwd /home/alex $ go literature [ /home/alex/literature ]