원문 : http://www.well.ox.ac.uk/~johnb/comp/unix/ksh.html
쉘타입의 정의
새로운 쉘스크립트를 만들때, 첫라인에 다음과 같이 써준다
다음:
#!/usr/bin/ksh
정확한 ksh 의 위치를 써주어야 하며, 32 character 를 넘어가면 안된다.
첫라인에 써주는 이정의로, 아래쪽의 모든스크립트는 ksh 가 처리하게 된다.
정의를 해주지않으면, 유저의 기본 쉘환경으로 지정된 쉘이 처리한다.
하지만 약간씩 다른 syntax 가 있기 떄문에 정확한 정의가 꼭 필요하다
4가지 종류의 행
스크립트는 4가지 종류의 라인정의가 있다:
최상단의 쉘정의 라인, 공란 라인, #으로 시작하는 주석 라인, 명령어라인.
아래의 예제를 보자:
#!/usr/bin/ksh
# Commentary......
file=/path/file
if [[ $file = $1 ]];then
command
fi
스크립트의 시작과 끝스크립트는 처음 line 으로 시작해서, "exit" 문구를 만나거나, 마지막 라인까지 실행된다. 모든 "#"으로 시작하는 라인은 무시된다.
명령어의 시작과 끝명령어의 시작은 라인의 첫번째 단어또는, ";"로 구분된 후 처음단어로 시작할 수 있다.
명령어의 끝에는 ";" 를 쓰거나 쓰지 않을 수 있다.:
print -n "Name: "; read name; print ""
"\"를 이용하면, 라인이 넘어가는 명령어를 한라인 같이 연결하여 입력할 수 있다.
grep filename | sort -u | awk '{print $4}' | \
uniq -c >> /longpath/file
스크립트 파일의 이름과 권한스크립트는 다른 unix 명령어와 이름이 동일할 수 없다. :
그래서 "test" 같은 이름으로 정할 수 없다. ( 주: test 도 unix 명령어중 하나 )
스크립트 저장후, 실행을 위해서 실행권한이 필요하다. :
chmod 700 filename
--------------------------------------------------------------------------------변수
변수 값
채우기변수값 채우는 방법은 이름을 이용하면 된다:
state="US"
숫자할당도 동일하다:
price=50
사용하기변수를 사용할때는 $ 기호를 변수앞에 붙여주면 된다:
print $state $price
배열변수 할당 및 사용하기:
arrname[1]=4 할당
print ${arraname[1]} 출력
${arrname[*]} 모든 배열 얻기
${#arrname[*]} 배열갯수 얻기
선언
ksh 에서는 변수를 선언한후 쓸필요는 없다. One cannot have decimals only integers. ( 주. 잘모르겠음요;; )
--------------------------------------------------------------------------------분기문
if then fi
if [[ $value -eq 7 ]];then
print "$value is 7"
fi
또는:
if [[ $value -eq 7 ]]
then
print "$value is 7"
fi
또는:
if [[ $value -eq 7 ]];then print "$value is 7";fi
if then else fi
if [[ $name = "John" ]];then
print "Your welcome, ${name}."
else
print "Good bye, ${name}!"
fi
if then elif then else fiif [[ $name = "John" ]];then
print "Your welcome, ${name}."
elif [[ $name = "Hanna" ]];then
print "Hello, ${name}, who are you?"
else
print "Good bye, ${name}!"
fi
case esac
case $var in
john|fred) print $invitation;;
martin) print $declination;;
*) print "Wrong name...";;
esac
추가 테스트(주.)
name="HanTaeJong";
if [ $name = "anTaeJong" ]
then
print "then Name: $name";
else
print "else Name: ${name}";
fi
print $name;:: if 조건문 [] 하나만 써도 됨:: $name , ${name} 차이 없음
--------------------------------------------------------------------------------반복문
while do done
while [[ $count -gt 0 ]];do
print "\$count is $count"
(( count -= 1 ))
done
until do done
until [[ $answer = "yes" ]];do
print -n "Please enter \"yes\": "
read answer
print ""
done
for var in list do done
for foo in $(ls);do
if [[ -d $foo ]];then
print "$foo is a directory"
else
print "$foo is not a directory"
fi
done
continue...break
해당반복을 스킵하고 다음반복을 진행하고 싶은경우:
"continue".
while read line
do
if [[ $line = *.gz ]];then
continue
else
print $line
fi
done
루프문종료를 원할경우:
"break".
while read line;do
if [[ $line = *!(.c) ]];then
break
else
print $line
fi
done
--------------------------------------------------------------------------------명령행 인수
(공식적으로는 "positional parameters" 라고 한다)
명령행 인수의 갯수는 $# 에 저장되어 있다. 그러므로,명령행 인수가 들어왔는지 여부를위해:
if [[ $# -eq 0 ]];then
print "No Arguments"
exit
fi
각각의 인수는 $1, ....$n 순서대로 저장되어있으며, $* 에 모든 인수가 저장되어 있다.
인수는 수정될 수 없지만, 추가는 가능하다.
만약 첫번째 인수로 $first 변수를 삽입하는 경우:
if [[ $1 != $first ]];then
set $first $*
fi
shift 커맨드를 이용하여, 인수의 제거도 가능함. 첫번째 인수부터 하나씩 제거됨
until [[ $# -eq 0 ]];do
# commands ....
shift
done
for 반복문을 이용하여, 인수의 활용도 가능하다. (기본변수 arg ) $*:
for arg;do
print $arg
done
프로그래명은 $0 에 저장되나, 경로까지 같이 저장됨!
--------------------------------------------------------------------------------비교기호
문자비교인 경우 같다는 "=" 같지않다 "!=" 를 사용한다.
숫자비교인 경우 같다 "-eq" 같지않다 "-ne" 크다 "-gt" 작다 "-lt" 를 사용한다.
if [[ $name = "John" ]];then
# commands....
fi
if [[ $size -eq 1000 ]];then
# commands....
fi
조건문의 연결로 그리고 "&&" 또는 "||" 의미로 사용할 수 있다.
if [[ $price -lt 1000 || $name = "Hanna" ]];then
# commands....
fi
if [[ $name = "Fred" && $city = "Denver" ]];then
--------------------------------------------------------------------------------변수 변경하기
변수에서 필요없는 부분의 제거변수에 포함되어 있는 경로부분을 제거할때 이용:
${name##*/}
파일명만 남기고 나머지를 삭제해줌
경로만 남기고 싶을때:
${name%/*}
% 왼쪽부분을 취할때 # 오른쪽부분을 취할때%% , ## 가장긴 부분 % ,# 가장 짧은 부분
할당되지 않은 변수에 대하여 임시변수 할당
$foo 라는 변수에 변수가 아직 할당되지 않았을 경우 할당하고 싶을때:
${foo:-4}
하지만 이렇게 하더라도 아직 변수는 할당되지 않은채로 있음.
할당되는걸로 바꾸고 싶은 경우:
${foo:=4}
(주. 예제가 필요해서 추가 함)
#foo=1;
print ${foo:-4};
print $foo;
print ${fpp:=4};
print $foo;
#주석처리된 foo=1; 을 주석제거 하고 안하고를 비교해보면 잘 알수 있음
변수가 할당되지 않았을 경우의 활용
해당변수가 할당되지 않을 경우 해당문구 출력(해당라인에서 실행중단):
${foo:?"foo not set!"}
변수 체크
${foo:+1}
변수가 할당된 상태면 1을 할당함,
그렇지 않을경우 할당하지 않음
--------------------------------------------------------------------------------Ksh 정규표현식
Ksh 는 자신만의 정규표현식을 갖는다. * 는 모든 문자를 뜻한다. 그러므로 .c 로 끝나는 모든 문자는 *.c 를
사용하면 된다.? 는 문자개를 뜻한다.:
?44.f.ksh 에서 패턴의 수를 정하는 한정자이다.:
?(pattern) 0,1 번 패턴.
*(pattern) 0번이상 패턴.
+(pattern) 1번이상 패턴.
@(pattern) 1번 패턴.
!(pattern) 괄호안의 문자그대로 패턴.
다음은 어떤문자와 매치될런지 생각해보자:
if [[ $var = fo@(?4*67).c ]];then ...
--------------------------------------------------------------------------------함수설명
함수( 프로시져)는 반드시 호출전에 정의되어 있어야한다.
왜냐하면, ksh 는 인터프리터 이기 때문에 함수 호출시 명령행 인수를 제외한 모든게 선언이 되어 있어야 하기 때문이다.
함수 정의둘중에 하나의 방법으로 정의 할 수 있다:
function foo {
# commands...
}
foo(){
# commands...
}
함수호출스크립트에 함수명을 쓰므로써 호출이 가능하다: foo. 인수를 주는방법은 다음과 같다:
foo arg1 arg2 ...
인수는 명령행과 동일하게 $1...$n 로 처리하며 $* 로 모든인수를 볼수 있다.
메인의 $1 는 함수내의 $1 에 영향을 받지 않는다.
Return return 명령어는 즉시 함수를 종료한다.
(주. return 시에 return 값을 줄수 없는거 같은데 맞는지 모르겠음 ㄷㄷㄷ )
--------------------------------------------------------------------------------데이터 리다이렉션
일반데이터의 리다이렉션은 다음과 같이 쓸수 있다: "> >> < <<".
모든 프로그램은 적어도 표준입력, 표준출력 그리고 표준오류출력을 갖는다.
이 세가지 모두 리다이렉션이 가능하다..
프로그램 실행후 결과값 파일로 저장하기결과파일을 생성하거나 덮어써서 기록하기:
command > file
기존파일에 이어쓰기:
command >> file
표준에러출력의 리다이렉션표준 에러출력을 리다이렉션 하기:
command 2> file
표준 에러출력을 버리기:
command 2>/dev/null
표준 에러출력을 표춘출력으로 전환 :
command 2>&1
프로그램에 파일 넣기프로그램이 표준입력을 받는다면 파일을 표준입력으로 입력 가능:
command < file
입력 출력 리다이렉션 결합
command < infile > outfile
command < infile > outfile 2>/dev/null
Commands into Program ( 주. 머라고 해야할지;; )
모든 유닉스 커맨드는 텍스트 리스트를 받을수 있다:
command <<EOF
input1
input2
input3
EOF
command 에 EOF ~ EOF 사이의 input 이 들어간다.
--------------------------------------------------------------------------------파이프
일련의 결과들이 다음커맨드로 이어져서 실행된다:
command1 | command2 | command3 ...
e.g. last | awk '{print $1}' | sort -u.
--------------------------------------------------------------------------------협업처리
One can have one background process with which one can comunicate with read -p and print -p. It is started with command |&. If one uses: ksh |& then this shell in the background will do everything for us even telnet and so on:
print -p "telnet hostname".
------------------------------------------------------------------사용자 또는 파일로부터 읽어들이기
변수에서 읽기유저로부터 입력을 받을때, newline 의 무시를 위해 -n 옵션을 이용한다.:
print -n "Enter your favorite haircolor: ";read var; print ""
파일에서 라인을 읽고 저장하기파일에서 반복적으로 읽기:
{ while read myline;do
# process $myline
done } < filename
파이프라인을 이용하여 결과의 마지막을 읽기:
last | sort | {
while read myline;do
# commands
done }
--------------------------------------------------------------------------------특별한 변수들
$# 명령행의 인수 수.
$? 마지막 명령어의 종료상태.
$$ 실행중인 프로그램의 ID.
$! 마지막으로 실행한 백그라운드 잡 또는 함수의 ID
$0 프로그램의 이름 path 포함, 다른 디렉토리에서 실행했어도 포함함.
$1..n 명령행 인수
$* 모든 명령행 인수 1개의 문자열.
--------------------------------------------------------------------------------명령어의 성공과 실패첫번째 명령어가 실행되었을때만 연결해서 실행하기:
command1 && command2.
첫번째 명령어가 실패하면 두번째 명령어 실행하기:
command1 || command2.
--------------------------------------------------------------------------------간단한 계산
간단한 계산식은 let 을 쓰거나 (( ... )) 안에 써서 실행이 가능함.
"$"을 쓰지 않는다.
1씩 증가하는 간단한 식:
(( a+=1 )) or let a+=1.
(주. 아래부터는 생략함 )!
--------------------------------------------------------------------------------Numerical Calculations using "bc"For bigger caluculations one uses "bc" like:
$result=$(print "n=1;for(i=1;i<8;i++)n=i*n;n"|bc)
--------------------------------------------------------------------------------"grep"
Search for the occurence of a pattern in a file: grep 'pattern' file. If one just wants to know how often soemthing occurs in a file, then: grep -c 'pattern file. This can be used in a script like:if [[ $(grep -c 'pattern' file) != 0 ]];then ......;fi. The condition is fullfilled if the pattern was found.
--------------------------------------------------------------------------------"sed"
Sed means stream line editor. It searches like grep, but is then able to replace the found pattern. If you want to change all occurences of "poor" with "rich", do:sed -e 's/poor/rich/g' filename. Or what is often seen in software packages, that have to be compiled after getting a propper configuration, is a whole file stuffed with replacements patterns like: /@foo@/s;;king;g. This file with inumerable lines like that has to be given to sed with: sed -f sedscript filename. It then precesses each line from file with all the sed commands in the sedscript. (Of course sed can do much more:-))
--------------------------------------------------------------------------------"awk"
Awk can find and process a found line with several tools: It can branch, loop, read from files and also print out to files or to the screen, and it can do arithmetics.For example: We have a file with lines like: Fred 300 45 70 but hundreds of them. But some lines have a "#" as the first sign of them and we have to omit these ones for both, processing and output. And we want to have lines as output like: 415 Fred where 415 is the sum of 300, 45 and 70. Then we call on awk:awk '$1 !~ /^#/ && $0 ~ /[^ ]/ {print $2+$3+$4,"\t",$1}' filename.This ignores lines with a "#" at the beginning of the first field and also blank lines. It then prints the desired sum and the $1 ist only printed after a tab. This is the most trivial use of awk only.Check my AWK programming introduction bye clicking on this sentence!
--------------------------------------------------------------------------------"perl"
Perl is a much richer programming language then ksh, but still one can do perl commands from within a ksh script. This might touch Randal, but it's true. Let's say you want to remove all ^M from a file, then take perl for one line in your ksh script:perl -i -ep 's/\015//g' filename.Perl can do an infinite amount of things in many different ways. For anything bigger use perl instead of a shell script.Check my PERL programming introduction bye clicking on this sentence!