Skip to content

쉘 프로그래밍 문법

MintState January 5, 2009 at 11:36 AM Views 20502

쉘 프로그래밍 문법

1. 매개변수(파라메타)
쉘 변수에는 세가지 유형이 있으며 이는 매개 변수로 알려져 있다. 그종류는 키워드
매개 변수, 위치 매개변수, 특수 쉘 매개변수 등이다.

1) 키워드 매개 변수
키워드 매개변수명은 알파벳 문자나 _ (밑줄) 문자로 시작 되어야 한다. 그리고 그
다음에는 알파벳이나 밑줄문자의 임의의 숫자가 올 수 있다. 그 값들은 다음과 같이
기록함으로써 키워드 매개변수에 배정된다.
변수=값 변수=값 ...

2) 위치 매개 변수
쉘 프로그램이 실행될 때마다 프로그램명은 변수 $0에 배정되고, 명령 라인에 타이
프된 인수들은 변수 $1, $2, $3 ...에 배정된다. 위치 매개변수들 set 명령으로 값
을 배정 받을 수 있다. $9 이상의 매개변수는 ${nn}으로 표현할 수 있다.
Examples:

$ cat hi 
print hello $1 
$ hi there world 
hello there 

3) 특수 매개 변수
$# 프로그램에 전달된 인수들의 수 또는 set문 실행에 의해 세트된 매개 변수들
의 수
$* $1, $2, $3 ...과 같은 모든 위치 매개변수들을 집단적으로 참조
$@ $* 과 같이 위치 매개변수들을 집단적으로 참조
$0 실행중인 프로그램 이름
$$ 실행중인 프로그램의 프로세스 번호
$! 실행을 위해 백그라운드로 보내진 마지막 프로그램의 프로세스 번호
$? 백그라운드로 실행되지 않은 마지막 명령의 종료 값
$- 현재 설정된 옵션값

2. 매개변수 치환
가장 간단한 경우로서, 매개변수의 값은 달러표시($)를 가진 매개 변수를 선행함으
로써 접근될 수 있다. 매개 변수의 치환은 파일명 치환전에, 그리고 명령 라인이
인수로 분리되기 전에 쉘에 의해 수행된다.
$parameter 또는 ${parameter}
매개변수의 값을 치환한다.
$ print $PWD ${11} $$
/usr/dgk arg11 1234
$ file=test_f
$ cp $file ${file}x
$
$ ls -x
$ test_f test_fx
${parameter:-value}
parameter의 값이 null이 아닌 경우 그값을 치환하고, null인 경우에는
value값만을 치환.
$ EDITOR=/bin/ed
$ echo ${EDITOR:-/bin/vi}
/bin/ed
$ EDITOR=
$ echo ${EDITOR:-/bin/vi}
/bin/vi
$ echo $EDITOR
$
${parameter:=value}
parameter값이 null이 아닌경우 그값을 치환하고, null인 경우 value값을
치환하고 그것을 parameter에 대입.
$ unset x
$ typeset -u x
$ print ${x=abc}
ABC
$
$ BOOKS=
$ : ${BOOKS:=$HOME/books}
$ echo $BOOKS
/usr/kys/books
$ : ${BOOKS:=tester}
$ echo $BOOKS
/usr/kys/books
$
${parameter:?value}
parameter 값이 null이 아닐경우 그값을 치환. 그렇지 않으면 value을 표준
에러에 기록하고 빠져나옴.
만약 value가 생략되어 있으면 parameter와 메서지를 출력프로그램에서 요구
되는 변수들이 모두 설정되었는지 또는 무효가 아닌지의 여부를 알아보기위
해 쉽게 사용하여 체크할수 있다.
$ print ${foo?}
ksh: foo: parameter null or not set
$ BOOKS=
$ : ${BOOKS:?"No BOOKS file"}
No BOOKS file
${parameter:+value}
parameter가 null이 아닐 경우 value를 치환.  null인 경우 아무것도 치환
하지 않음.
$ set a b c
$ print ${3+foobar}
foobar
$
$ toption=
$ echo options: ${toption:+ "T mode"}
options:
$
${#parameter}
매개변수의 길이를 치환
$ HOME=/home/klog
$ print ${#HOME}
10
$
${#array[*]} , ${#array[@]}
배열의 요소들의 수를 치환
$ unset x
$ x[1]=5 x[3]=8 x[6]=abc x[12]=
$ print ${#x[*]}
4
${parameter#pattern}
매개변수의 값을 치환하며 이때 pattern과 부합되는 왼쪽 부분은 제거된다.
쉘 화일명 치환문자들(*,?,[..],@,!)을 사용할 수 있다.
$ cd $HOME/src/cmd
$ print ${PWD#$HOME/}
src/cmd
$
${parameter##pattern}
가장 큰 pattern과 부합되는 왼쪽 부분은 제거된다.
$ x=/one/two/three
$ print ${x##*/}
three
$
${parameter%pattern}
pattern과 부합되는 오른쪽 작은 부분이 제거된다.
$ x=file.c
$ print ${x%.c}.o
file.o
$
${parameter%%pattern}
pattern과 부합되는 오른쪽 큰 부분이 제거된다.
$ x=foo/fun/bar
$ print ${x%%/*}
foo
$

3. 파일 입출력

1) 파일 열고 닫기
exec 명령을 아무런 아규먼터 없이 사용하여 현재 환경에서 파일을 열고 닫을 수
있으며, I/O 방향재설정 방법을 사용하며 이때 파일디스크립터 값은 0-9까지 사용
할 수 있다.
Examples:
exec 3< foo  <- foo을 파일디스크립터3 으로 지정하여 읽기위해
open
$ exec 3<&- <- 파일디스크립터3 을 close

4. 다큐먼트, 반환값

1) 다큐먼트
문자 #로 단어가 시작된다면 셀은 라인의 나머지를 주석으로 취급하고 ksh이 실행하
지 않는다
Examples:

$ cat samp_1 
# This is comment line 
# pwd 
ls -x        # display listing of the directory 
$ samp_1 
samp_1 samp_2 samp_3 samp_4 samp_5 
$ 

2) 반환값
각각의 명령어는 반환값을 가진다. 명령어의 반환값은 조건 명령이나 순환명령에서
많이 사용된다. 반환값은 0에서부터 255의 값을 가진다.
반환값 0 은 정상적인 종료인 경우의 값이며 조건이나 순환명령어에서 TRUE로 사용
되는 값이다. 그 이외의 모든 다른 값은 FALSE로 취급된다.
반환값 1은 명령의 실행이 실패한 경우 129-160은 명령어가 신호를 수신하고 종료한
경우에 발생되는 값이다.
ksh에서는 $? 변수에 가장 최근에 종료된 명령어의 반환값이 저장된다.
 

5. 병렬 프로세스 기능
병렬프로세스 기능은 동시에 실행되면서 상호간에 통신하고 동기화를 하는 프로세스
간의 상호 작용 기능을 제공한다. 병렬프로세스의 시작은 명령어 라인의 끝에 "|&"
을 추가하므로서 구현할 수 있다.
기본적으로 병렬 프로세스의 표준입력은 그 프로세스의 부모 프로세스의 표준 출력
과 연결되며, 병렬 프로세스의 표준 출력은 그 프로세스의 부모 프로세스의 표준 입
력과 연결된다.

cat /etc/passwd |& 
while true 
do 
if [ -z "$FLINE" ] 
then 
  exit 0 
else 
  read -p FLINE 
fi 
echo $FLINE 
done 

6. 쉘 스크립트 실행 방법

1) . Script ( Dot Command )
도트 명령은 지시된 파일이 마치 그 파일로 부터의 라인들이 그지점에서 타이프 된
 것처럼 쉘에 의해 판독되고 실행되도록 한다. file은 실행하도록 하는 것이 아니
라 다만 읽기 쉽게 한다.
Examples:

$ cat > .profile 
export PS1='$PWD> ' 
export PATH=$PATH:$HOME 
^d 
$ . .profile 
/home/edu01> _ 

-> 변경된 .profile의 내용을 로그아웃, 로그인 순서를 그치지 않고 현재 쉘
에서 실행하여 사용자 환경을 지정할 수 있다.

2) ksh script_filename
서브쉘을 생성하여 그 쉘이 스크립트를 읽어서 실행하도록 한다. 이 경우
script_filename 파일이 실행 퍼미션이 지정되어 있지 않아도 된다.
Examples:

$ cat > test_sub_shell 
echo "test execution of shell script file " 
echo $PWD 
^d 
$ 
$ ls -l test_sub_shell 
-rw-r--r-- 1 edu01 other 54 Jan 29 10:00 test_sub_shell 
$ ksh test_sub_shell 
test execution of shell script file 
/home/edu01 
$ 

3) chmod +x script_filename
script 파일에 실행 퍼미션을 설정하여 실행한다.
Examples:

$ chmod +x test_sub_shell 
$ ls -l test_sub_shell 
-rwxr-xr-x 1 edu01 other 54 Jan 29 10:00 test_sub_shell 
$ test_sub_shell 

ksh: No such file or directory
-> 현재 디렉토리 경로가 PATH에 설정되어 있지 않다.
$ export PATH=$PATH:.
-> 현재 디렉토리를 PATH 환경변수에 설정한다
$ test_sub_shell
test execution of shell script file
/home/edu01
$

7. 파일과 문자 테스트 연산자
test 명령이나 [ ... ] 연산 결과 TRUE로 반환 받는 조건이다.

1) 파일연산자
-r file 프로세스에 의해 판독가능한 파일
-w file 프로세스에 의해 기록 가능한 파일
-x file 프로세스에 의해 실행 가능한 파일
-f file 보통 파일
-d file 디렉토리
-c file 문자 특수 파일
-b 2file 블록 특수 파일
-p file 파이프 파일
-u file 파일이 SUID(집합사용자 확인) 비트세트를 가진 경우
-g file 파일이 SGID(집합그룹확인) 비트 세트를 가진 경우
-k file sticky bit이 설정된 파일
-s file 비제로 길이를 가진 파일
-L file 심볼릭 링크 파일
-O file 파일의 주인이 effective user id인 경우
-G file 파일의 그룹이 effective user id인 경우
-S file socket 형태의 특수 파일인 경우
-t file file descriptor가 어떤 단말기와 연관된 개방된 파일 디스크립
터인 경우

2) 스트링 연산자
string 스트링이 널이 아닌 경우
-n string 스트링이 널이 아닌경우
-z string 스트링이 널인 경우
string1 = string2 string1 과 string2 가 같은 경우
string1 != string2 string1 과 string2 가 같지 않은 경우

3) 정수 비교 연산자
int1 -eq int2 int1 이 int2 와 같은 경우
int1 -ge int2 int1 이 int2 와 같거나 그보다 큰경우
int1 -gt int2 int1 이 int2 보다 큰경우
int1 -le int2 int1 이 int2 와 같거나 작은 경우
int1 -lt int2 int1 이 int2 보다 작은 경우
int1 -ne int2 int1 이 int2 와 같지 않은 경우

4) 부울 연산자
!expr expr이 FALSE
expr1 -a expr2 expr1이 TRUE, 그리고 expr2가 TRUE
expr1 -o expr2 expr1이 TRUE 혹은 expr2가 TRUE
Examples:

$ test -x file -a ! -d file 
-> file이 실행 가능하고 디렉토리가 아닌 경우 
$ test "x$1" = xabc 
-> $1이 abc인 경우 
$ [ "x$1" = xabc ] 
-> $1이 abc인 경우 
$ test ! ( -w file -o -x file ) 
-> file 이 쓸 수 있거나 실행 가능한 파일이 아닌경우 
$ [ ! ( -w file || -x file ) ] 
-> file 이 쓸 수 있거나 실행가능한 파일이 아닌경우 

8. 내장된 정수 연산

1) 정수 연산
일반적인 대부분의 수식 연산을 ksh 에서는 지원하고 있다. 다음은 ksh에서 지원 되
는 연산자들이다.

-             단항 - 
~            NOT 
!            논리부정 
* , / , %    곱하기, 나누기, 나머지 
+ , -        더하기, 빼기 
<< , >>      왼쪽 시프트, 오른쪽 시프트 
< , > , <= , >=     비교 
== , !=      동등, 비동등 
&             그리고 
^             배타적 또는 
|             또는 
&&            논리적 and 
||            논리적 or 
=             배정 

2) let 명령
Korn쉘은 expr 명령없이 정수 연산을 수행하기 위한 메커니즘을 제공하고 있는데 그
것이 let 명령이다. let은 쉘에 내장되어 있기 때문에 계산을 위한 새로운 과정을
만들거나 찾거나 프로그램을 로딩할 필요도 없다. let의 형식은
$ i=100
$ let i = i + 1
$ echo $i
101
$
$ let ' i = i + 1 ' 'j = j + 10'
개별적인 식들이 중간에 공백으로 가지고 있다면 인용부호로 묶어서 사용해야하며
이것은 수식 쉘로부터의 *, &, <, > 와 같은 문자들이 가지는 특별한 의미를 제거하
는 부가적 효과를 가진다.
$ let 'i = ( i + 10 ) * j '
둥근 괄호를 이용하여 수식을 그룹화할 수도 있다.
 
3) (( expression ))
(( expression )) 은 let "expression" 과 같은 의미이다. 쌍으로된 둥근 괄호를 이
용하여 let에 대한 대안적 형식을 취할수 있다.
$ (( i = i * 5 ))
$ (( i >= 0 && i <= 100 ))

4) expr
expr 명령을 사용하여 수식 계산을 실행한 후에 변수에 그 값을 지정한다.
Examples:

$ aa=10 
$ aa=`expr $aa + 10` 
$ echo $aa 
20 
$ 

5) integer variable
수식계산에 사용되는 변수를 정수로 선언하여 일반적인 형태의 수식계산 방식을 ksh
에서 사용하도록 지정한다. 하지만 이렇데 지정된 변수는 반드시 정수 값만 가질수
있다.
Examples:

$ integer aa 
$ aa=100 
$ aa=aa+1 
$ echo $aa 
101 
$ aa="test a integer variable" 
ksh: aa: bad number 
$ 

9. 배열
Korn쉘은 제한된 배열 능력을 제공한다. 배열은 1차원으로 512요소를 가지며, 배열
의 인덱싱은 0에서 시작하고 511까지 지정할수 있다.
배열의 요소는 한쌍의 각괄호( [ ] ) 안에 넣어진 정수값으로 된 색인첨자와 함께
호출되는 것으로 자신이 요구하는 만큼 요소에 값을 할당하여 사용한다.
$ arr[0]=hello
$ arr[1]="some text"
$ arr[2]=/home/dgk/memos
배열로부터 값을 불러오는 방법은 배열의 이름과 각 괄호안에 원하는 요소의 번호를
넣고 그것을 ${ }에 넣어 사용한다.
$ echo ${arr[0]}
hello
$ echo ${arr[2]}
/home/dgk/memos
$ echo $arr
hello
-> 첨자가 없는 경우 요소 0이 이용된다.
$ echo $arr[1]
hello[1]
-> { }을 사용하지 않고 출력한 경우 예상치 않은 결과 값을 출력한다.
$
$ echo ${arr[*]}
hello some text /home/dgk/memos
-> 배열에 들어있는 모든 내용을 불러 온다
$
$ echo ${#arr[*]}
3
-> 배열 arr에 있는 요소들의 갯수. 이때 수는 실제 요소의 갯수가 아니고
가장 큰 첨자 + 1 한 값이 출력된다. 이 값은 배열안에 다음 요소를 저장하
기 위한 첨자로 사용된다.
$
$ arr[10]=foo
$ echo ${arr[*]}
hello some text /home/dgk/memos foo
$ echo ${#arr[*]}
11
-> 사용자가 정수 명령을 배열명에 선언해 줌으로써 Korn쉘에게 정수 배열을
선언하게 한다.
$ integer arr
$ arr[0]=100
$ arr[1]=50
$ (( arr[2] = arr[0] + arr[1] ))
$ echo ${arr[2]}
150
$

배열구성요약
${array[i]} 요소 i 값을 치환
$array 첫번째 요소 array[0]값을 치환
${array[*]} 모든 요소값을 치환
${#array[*]} 요소들의 수를 치환
array[i]=value value을 array[i]로 치환

10. 함수 정의
ksh에서의 function명령은 name ( ) { ....; } 형식으로 선언된다. 기능을 분류하거
나 순환적으로 일어나는 일들을 하나의 변수 형식으로 지정하여 불러 사용할 수 있
도록 한다.
function identifier
{
       compound-list
}
identifier( )
{
       compound-list
}
Examples: 등록된 사용자수를 세는 nu 라는 함수를 정의한다.

$ function nu 
{ 
 who | wc -l 
} 
$ nu 
13 
$ 
$ cat funt1 
function check_yesno 
{ 
 typeset -l reply 
 while true 
 do 
 read -r "reply?$1? " || return 1 
 case $reply in 
       y|yes} return 0;; 
       n|no) return 1;; 
       *) print 'please answer y or n';; 
 esac 
 done 
} 
while check_yesno 'Do you want to continue? ' 
do 
 foobar 
done 
$ 

일반적으로 정의된 함수는 서브쉘에 보내지지 않는다. 하지만 typeset이라는 명령을
사용하여 함수정의를 export 시킬 수 있다.
$ typeset -fx funtion-name -> function-name을 주지 않으면 엑스포트된 함수들의 명단을 출력한다.
$ typeset -f -> 정의된 함수의 리스트를 출력한다.
funcrion nu
{
    who | wc -l
}
$
함수정의 삭제
함수정의를 삭제하기 위해 -f 옵션을 가진 unset명령을 사용한다.

$ type nu 
nu is a function 
$ unset -f nu 
$ type nu 
ksh: nu: not found 
$ 

11. 변수의 속성 정의
매개변수의 종류는 앞에서 키워드 매개변수, 위치매개변수, 특수매개변수로 나누어
설명하였다. 이런 각각의 변수는 하나 또는 그 이상의 특성을 정의할 수 있으며
typeset 이라는 명령어를 사용하여 변수의 특성을 on/off 하거나 설정되어 있는 내
용을 리스트할 수 있다.
Command: typeset [-options] vasriable
Options:
-u Uppercase 소문자를 대문자로 변환한다. -l 옵션은 자동적으로 off된다
$ typeset -u x=abc
$ print $x
ABC
-l Lowercase 대문자를 소문자로 변환한다. -u 옵션은 자동적으로 off 된다.
$ typeset -l x=ABC
$ print $x
abc
-i or -ibase Integer 정수 변수로 정의된다. base는 수의 진법 정의
$ integer x=6
$ typeset -i8 y=x+x
$ print $y
8#14
-L or -Lwidth Left-justified 앞에오는 공란들을 왼편 자리 맞춤시키고
스트립 시킴. width가 비제로로 정의 되어 있으면 자리수를 width로 설정한다. -R옵
션은 자동적으로 off된다.
$ typeset -L3 x=abcd y
$ y=3
print "$y-$x"
3 -abc
-LZ or -LZwidth Strip Leading Zero 앞에오는 제로들은 스트립되고 왼
편으로 자리 맞춤한다.
$ typeset -LZ3 x=abcd y
$ y=03
print "$y-$x"
3 -abc
-R or -Rwidth Right-justified 오른편 자리 맞춤시키고 스트립시킴.
width가 비제로인 경우 자리수를 width 로 설정.
$ typeset -R3 x=abcd y
$ y=3
$ print "$y-$x"
3-bcd

-Z or -Zwidth Zero-filled
-RZ or -RZwidth Zero-filled
-Z만 설정된 경우 -L 옵션이 굛 되어있지 않다면 오른편로 자리 맞춤 시키고 스트립
시킨다. width가 비제로 값이면 자리수를 width로 설정한다. 만약 처음의 비공란 문
자가 숫자이면 0으로 채워진다.
$ typeset -Z3 x=abcd y
$ y=3
$ print "$y-$x"
003-bcd
-r Read-only 변수가 읽기전용으로 설정되어 있다면 그 변수값을 변경하려 하
면 에러 메세지를 출력하고 변경이 불가능하다.
$ typeset -r foo=bar
$ foo=nobar
ksh: foo: is read only
$ unset foo
ksh: foo: is read only
-x Exported 모든 변수에 값이 설정되면 자동적으로 현재 환경에 값을 배당
한다.
$ typeset -x foo=bar
$ export foo=bar

12. 패턴
[ . . . ] 부호 문자들을 정의하여 그중 어느 하나의 문자와 일치하는 패턴 정
의할수 있다. ' - ' 부호를 사용하여 범위를지정 할수 있다. ' ! ' 부호를 사용하여
역으로 매치 시킬수도 있다.

$ ls 
chap1 chap10 chap11 chap2 chap3 chapa chapb chapc 
$ ls chap[123] 
chap1 chap2 chap3 
$ ls chap[12][01] 
chap10 chap11 
$ ls chap[!2-4] 
chap1 
$ ls chap[1-3] 
chap1 chap2 chap3

 
? 문자 어떤 문자이든 상관없이 한 문자와 매치 된다

$ ls chap? 
chap1 chap2 chap3 
chapa chapb chapc

 
* 문자 어떤 문자든 0번 또는 그 이상과 매치
$ ls chap*
-> chap 으로 시작되는 모든 스트링
$ ls x*y
-> x로 시작하고 y로 끝나는 모든 스트링
?(pattern[|pattern]...) 패턴 0번 또는 한번 발생되는 pattern과 매치
$ ls para?([345]|99)1
-> para1, para31, para41, para51, para991 과 매치
*(pattern[|pattern]...) 패턴 0번 이상 발생되는 pattern과 매치
$ ls para*([0-9])
-> para, para뒤에 어떤 숫자라도 붙어 있는 스트링과 매치
+(pattern[|pattern]...) 패턴 1번 이상 발생되는 pattern과 매치
$ ls para+([0-9])
-> para뒤에 숫자가 붙어 있는 모든 스트링과 매치
@(pattern[|pattern]...) 패턴 정확히 한번 발생되는 pattern과 매치
$ ls para@(chute|graph)
-> parachute, paragraph 과 매치
!(pattern[|pattern]...) 패턴 pattern에 정의된것을 제외한 모든것과
매치
$ ls para!(*.[0-9])
-> para로 시작하고 .숫자로 끝나지 않는 모든 스트링과 매치

13. 조건문
[ [ test-expression ] ] 또는 [ test-expression ] 기호
test 명령을 대신하여 테스트하는데 사용할 수 있다.
$ [ [ foo > bar && $PWD -ef . ] ] && print foobar
foobar

1) if . . . then . . . else . . . fi
if 는 일반적으로 3가지 패턴으로 사용할수있다.
형식1:
if test -f $1
then
  echo $1 exist
fi
형식2:
if test -f $1
then
echo $1 exist
else
  echo $1 does not exist
fi
형식3:
if (( score < 65 )
then grade=F
elif (( score < 80 )
then grade=C
elif (( score < 90 )
then grade=B
else grade=A
fi
Examples:

if print 'Please enter your name: c' ; read -r name 
then if mail "$name" < mailfile 
     then : 
     else print "Cannot mail to $name" 
     fi 
else print 'end-of file'
     exit 1 
fi 

2) case
case word in
[ ( ) pattern [ | pattern.... ] ... ] compound-list ;; ]
. . . .
esac
word와 매치되는 pattern을 찾아서 해당되는 compound-list를 실행한다.
Examples:

$ cat case1 
case $x in 
-d*) dflag=1;; 
-e*) eflag=1;; 
"") print -r -u2 - "x must have a value";; 
*) if test ! -r "$x" 
   then print -r - "$x: no read permission" 
   fi ;; 
esac

 

$ cat case2 
read -r line 
case $line in 
[$1]*) : ;; # ok 
*) print 'Line must begin with one of: $1" 
   exit 1;; 
esac 

14. 반복

1) for 문
for identifier [ in word .... ]
do compound-list
done
word의 개수만큼 do와 done사이의 명령어들을 반복적으로 실행한다
Examples:

$ cat for1 
for i in apple banana mango 
do 
  echo "$it" 
done 
$ 
$ for1 
apple banana mango 
$ 

 

$ cat for2 
for i in *   ## 현재 디렉토리의 모든 파일 
do 
if test -d "$i" 
then print -r - "$i" 
fi 
done

다음 예제는 트럼프 놀이를 쉘 스크립트로 작성한 것이다. 한번 <Enter> 키를 칠 때
마다 카드 번호를 한 장씩 출력해준다. 총 7장의 카드를 출력해준다.

$ cat for3 
integer i=0 ; typeset -u card 
echo "Gamer I : 이름을 입력하시오: c" 
read gamer01 
echo "Gamer II : 이름을 입력하시오: c" 
read gamer02 
echo "카드를 섞고 있습니다" 
for suit in clubs diamonds hearts spades 
do 
  for n in ace 2 3 4 5 6 7 8 9 10 jack queen king 
  do 
  card[i]="$n of $suit" 
  i=i+1 
  done 
done 
echo "게임을 시작하겠습니다" 
for gamer in $gamer01 $gamer02 
do 
  echo "$gamer: c" 
  i=0 
  while [ $i -le 7 ] 
  do 
    read 
    echo " ${card[RANDOM%52]} t" 
    i=i+1 
  done 
  echo 
done

 

2) select문
select identifier [ in word .... ]
do compound-list
done
나열하는 word를 화면에 메뉴 형태로 표준 출력 화면으로 출력해 주고, 표준 입력으
로부터 무한 반복으로 값을 입력 받는다. 값을 입력 받기위해 프롬프트를 출력해 주
는데 디폴트 프롬프트는 '?' 이다. 프롬프트는 환경변수 PS3에서 지정할 수 있다.
Examples:

$ cat select1 
PS3='Please enter a number: ' 
select i in add delete modify list exit 
do 
  case $i in 
  add|modify) 
    print Select editing file 
    break;; 
  delete) 
    print Select removing job;; 
  list) 
    print Select display job;; 
  exit) 
    print Select exit job 
    print Good-bye 
    exit ;; 
  *) print 'Invalid number';; 
  esac 
done 
$ select1 
1) add 
2) delete 
3) modify 
4) list 
5) exit 
Please enter a number:_ 

3) while문
while test문 또는 명령어 실행
do compound-list
done
while 반복문은 test문 또는 명령의 실행결과가 참(true)인 동안 루틴을 반복적으로
수행한다.
Examples:

$ cat while1 
while read -r line 
do 
  print -r - "$line" 
done

 

$ cat while2 
while [ $line -le $maxline ] 
do 
  echo >> $BUFFER 
  lines=`expr $lines + 1` 
done

 

$ cat while3 
while true 
do 
  read name 
  if [ ${name}x = x ] 
  then 
    break 
  fi 
done

 

4) until 문
until test문 또는 명령어 실행
do compound-list
done
test문 또는 명령 실행결과가 거짓(false)인 경우 루틴을 반복 수행한다.
Examples:

$ cat until1 
until cc -c foo.c 
do vi foo.c 
done

 

$ cat until2 
until who | grep klog >/dev/null 
do 
echo waiting 5 seconds 
sleep 5 
done 
echo klog has logged on

 

$ cat until3 
until false 
do 
  read name 
  if [ ${name}x = x ] 
  then 
    break 
  fi 
done 

15. 흐름 제어

1) break [ n ]
이 명령의 실행은 가장 안쪽 n개의 for, while, until 루프의 실행이 즉시 종료시키
고 빠져 나오며 루프다음의 명령을 계속 실행한다.
Examples:

$ cat break1 
for i in * 
do
  for j in foo bar bam 
  do 
     if test "$j" = "$i" 
     then 
        break 2 
     fi 
  done 
done 

2) continue [ n ]
for, while, until 루프안에서의 이명령의 실행은 continue 다음에 오는 임의의 명
령들이 skip 되도록 한다.
Examples:

$ cat continue1 
for i in * 
do 
  if test -d "$i" 
  then continue 
  fi 
  print -r - "$i is not a directory" 
done 
$ 

16. 쉘 프로그래밍 응용

1) vi with backup the file
vi 편집기를 호출하여 파일을 편집하여 저장하기전 이전의 파일을 filename.bak 파
일에 저장하도록 하는 쉘 스크립트를 작성한다.

$ cat vvi 
#!/usr/bin/ksh 
# 
if [ $# -le 0 ] 
then 
vi 
exit 
fi 
cp $1 ${1}.tmp 
vi $1 
if cmp -s $1 ${1}.tmp 
then 
  rm ${1}.tmp 
else 
  cp ${1}.tmp ${1}.bak 
  rm ${1}.tmp 
fi 

 
2) newcat
출력용 필터인 newcat 을 생성한다. 내용의 각 라인에 라인번호를 붙여서 23개 라인
씩 출력한다.

$ cat newcat 
#!/usr/bin/ksh 
if [ $# -lt 1 ] 
then 
  echo "Usage Error: newcat filenames... " ; exit 
fi 
for filename in $* 
do 
  integer count=1 
  integer page=1 
  exec < $filename 
  echo "Filename : $filenamettPage: $page " 
  while read line 
  do 
    if [ $count -eq 22 ] 
    then 
       echo "--More-- <Press Return> " 
       read 
       echo "f" 
       page=page+1 
       echo "Filename : $filenamettPage: $page " 
    fi 
    echo "$countt$line" 
    count=count+1 
   done 
done 

3) exec_check 실행 점검 스크립트
program_01 이라는 프로그램을 실행하는 스크립트를 작성한다. 이미 이 프로그램이
실행중이라면 30초간 대기하면서 이미 실행중인 프로그램의 실행종료를 대기한다.
대기중 실행종료가 확인되면 프로그램을 실행시킨다. 30초가 초과되면 타임아웃으로
인식하고 메시지를 출력하고 스크립트를 종료한다.

$ cat exec_check 
#!/usr/bin/ksh 
# 
trap "echo off > ex_check_file; echo "인터럽트 수신/종료"; exit 200" 2 
if [ $# -ne 1 ] 
then 
  echo "실행할 프로그램명이 입력되지 않았습니다" 
  echo "USAGE: exec_check program-name" 
  exit 
fi 
if [ ! -f ex_check_file ] 
then 
  echo off > ex_check_file 
fi 
integer count=0 
while read e_flag < ex_check_file; [ e_flag = 'on' ] 
do 
  echo "$1 프로그램이 실행중입니다. 프로그램 종료 대기중..." 
  sleep 5 
  count=count+1 
  if [ $count -eq 6 ] 
  then 
    echo "TIME OUT...." 
    echo "$1 프로그램이 아직 실행중입니다" 
    echo "잠시후 다시 실행하여 주십시오" 
    echo "스크립트를 종료합니다" 
    exit 
  fi 
done 
echo on > ex_check_file 
$1 
echo off > ex_check_file 
echo "$1 프로그램 실행을 정상 종료합니다"

 

4) 웹으로 finger을 실행하게 하는 CGI 프로그램

#!/bin/sh !/usr/bin/ksh 
FINGER=/usr/bin/finger 
echo Content-type: text/html 
echo 
if [ -x $FINGER ] 
then 
  if [ $# -eq 0 ] 
  then 
    cat << EOM 
    <HTML>
    <HEAD><TITLE>Finger Gateway</TITLE></HEAD> 
    <BODY> 
    <H1>Finger Gateway</H1> 
    <ISINDEX> 
    This is a gateway to "finger". Type a user@host combination in your 
browser's search dialog.<P> 
    EOM 
  else 
    echo <PRE> 
    $FINGER "$*" 
    echo </PRE> 
  fi 
else 
  echo Cannot find finger on this system. 
fi 
cat << EOM 
</BODY></HTML> 
EOM
Share X Facebook LINE QR code

0 comments

Be the first to comment.