행위

Ksh while

DB CAFE

1 쉘타입의 정의

새로운 쉘스크립트를 만들때, 첫라인에 다음과 같이 써준다

#!/usr/bin/ksh


정확한 ksh 의 위치를 써주어야 하며, 32 character 를 넘어가면 안된다.

첫라인에 써주는 이정의로, 아래쪽의 모든스크립트는 ksh 가 처리하게 된다.

정의를 해주지않으면, 유저의 기본 쉘환경으로 지정된 쉘이 처리한다.

하지만 약간씩 다른 syntax 가 있기 떄문에 정확한 정의가 꼭 필요하다


2 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
  • 그룹에 쓰기 권한 추가, 사용자에 읽기권한 제거
chmod g+w,o-r aaa.txt

3 변수

변수 값


채우기변수값 채우는 방법은 이름을 이용하면 된다:


state="US"


숫자할당도 동일하다:


price=50


사용하기변수를 사용할때는 $ 기호를 변수앞에 붙여주면 된다:


print $state $price


배열변수 할당 및 사용하기:


arrname[1]=4 할당

print ${arraname[1]} 출력

${arrname[*]} 모든 배열 얻기

${#arrname[*]} 배열갯수 얻기


선언


ksh 에서는 변수를 선언한후 쓸필요는 없다.



4 분기문

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} 차이 없음



5 반복문

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



6 명령행 인수

(공식적으로는 "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 에 저장되나, 경로까지 같이 저장됨!



7 비교기호

문자비교인 경우 같다는 "=" 같지않다 "!=" 를 사용한다.

숫자비교인 경우 같다 "-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



8 변수 변경하기

변수에서 필요없는 부분의 제거변수에 포함되어 있는 경로부분을 제거할때 이용:


${name##*/}

파일명만 남기고 나머지를 삭제해줌


경로만 남기고 싶을때:


${name%/*}


% 왼쪽부분을 취할때 # 오른쪽부분을 취할때%% , ##  가장긴 부분  % ,# 가장 짧은 부분


할당되지 않은 변수에 대하여 임시변수 할당


$foo 라는 변수에 변수가 아직 할당되지 않았을 경우 할당하고 싶을때:


${foo:-4}


하지만 이렇게 하더라도 아직 변수는 할당되지 않은채로 있음.

할당되는걸로 바꾸고 싶은 경우:


${foo:=4}


(주. 예제가 필요해서 추가 함)


#foo=1;

print ${foo:-4};

print $foo;

print ${fpp:=4};

print $foo;


  1. 주석처리된 foo=1; 을 주석제거 하고 안하고를 비교해보면 잘 알수 있음


변수가 할당되지 않았을 경우의 활용


해당변수가 할당되지 않을 경우 해당문구 출력(해당라인에서 실행중단):

${foo:?"foo not set!"}


변수 체크


${foo:+1}


변수가 할당된 상태면 1을 할당함,

그렇지 않을경우 할당하지 않음


9 Ksh 정규표현식

Ksh 는 자신만의 정규표현식을 갖는다. * 는 모든 문자를 뜻한다. 그러므로 .c 로 끝나는 모든 문자는 *.c 를

사용하면 된다.? 는 문자개를 뜻한다.:


?44.f.ksh 에서 패턴의 수를 정하는 한정자이다.:


?(pattern) 0,1 번 패턴.

  • (pattern) 0번이상 패턴.

+(pattern) 1번이상 패턴.

@(pattern) 1번 패턴.

!(pattern) 괄호안의 문자그대로 패턴.


다음은 어떤문자와 매치될런지 생각해보자:

if [[ $var = fo@(?4*67).c ]];then ...



10 함수설명

함수( 프로시져)는 반드시 호출전에 정의되어 있어야한다.

왜냐하면, ksh 는 인터프리터 이기 때문에 함수 호출시 명령행 인수를 제외한 모든게 선언이 되어 있어야 하기 때문이다.

함수 정의둘중에 하나의 방법으로 정의 할 수 있다:


function foo {
   # commands...
}

 

foo(){
   # commands...
}

함수호출스크립트에 함수명을 쓰므로써 호출이 가능하다: foo. 인수를 주는방법은 다음과 같다:


foo arg1 arg2 ...


인수는 명령행과 동일하게 $1...$n 로 처리하며 $* 로 모든인수를 볼수 있다.

메인의 $1 는 함수내의 $1 에 영향을 받지 않는다.

Return return 명령어는 즉시 함수를 종료한다.

(주. return 시에 return 값을 줄수 없는거 같은데 맞는지 모르겠음 ㄷㄷㄷ )



11 데이터 리다이렉션

일반데이터의 리다이렉션은 다음과 같이 쓸수 있다: "> >> < <<".

모든 프로그램은 적어도 표준입력, 표준출력 그리고 표준오류출력을 갖는다.

이 세가지 모두 리다이렉션이 가능하다..

프로그램 실행후 결과값 파일로 저장하기결과파일을 생성하거나 덮어써서 기록하기:


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 이 들어간다.


12 파이프

일련의 결과들이 다음커맨드로 이어져서 실행된다:


command1 | command2 | command3 ...


e.g. last | awk '{print $1}' | sort -u.



13 협업처리

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".



14 사용자 또는 파일로부터 읽어들이기

변수에서 읽기유저로부터 입력을 받을때, 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 }

15 특별한 변수들

$# 명령행의 인수 수.

$? 마지막 명령어의 종료상태.

$$ 실행중인 프로그램의 ID.

$! 마지막으로 실행한 백그라운드 잡 또는 함수의 ID

$0 프로그램의 이름 path 포함, 다른 디렉토리에서 실행했어도 포함함.

$1..n 명령행 인수

$* 모든 명령행 인수 1개의 문자열.



16 명령어의 성공과 실패첫번째 명령어가 실행되었을때만 연결해서 실행하기:

command1 && command2.


첫번째 명령어가 실패하면 두번째 명령어 실행하기:

command1 || command2.



17 간단한 계산

간단한 계산식은 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!


while true ;
do
ls -altr *.txt;
sleep 1;
done
  • grep 명령 제외하고
while true ;do ps -ef |grep SQL|grep -v "grep";sleep 5;clear;done