어째 다 읽어 보지도 못 하고 글만 올리는것 같습니다.

 나중에 꼭 봐야 지…

1. Shell Program 소개

u      Shell 종류

/usr/bin/sh      POSIX Shell

/usr/bin/ksh     Korn Shell

/usr/old/bin/sh  Bourne Shell

/usr/bin/csh     C Shell

/usr/bin/keysh   Key Shell

/usr/bin/rksh    Restricted Korn Shell

/usr/bin/rsh     Restricted Shell

u      Shell Startup 파일

Korn Shell     /etc/profile -> $HOME/.profile -> $HOME/.kshrc

Bourne Shell   /etc/profile -> $HOME/.profile

POSIX Shell    /etc/profile -> $HOME/.profile -> $HOME/.kshrc

C Shell        $HOME/.login -> $HOME/.cshrc

2.Shell Parameter

u      Parameter Substitution

l         Parameter Setting

# Parameter=Value

# 변수명=값  : Named Parameter

l         Parameter의 Unsetting

# unset parameter

  # unset 변수명

u        Command Substitution

# $(command)       # `command`

# XX=”12345″

# echo $XX

12345

# HOST=‘hostname‘

# echo $HOST     : # HOST=`hostname` 문장은 # HOST=$(hostname)과 같다

ssosvr3           : 즉, `command` 문장과 $(command)는 같은 뜻이다

# PS1=‘hostname‘’:$PWD# ‘

# PS1=$(hostname)’:$PWD# ‘; echo $PS1

ssosvr3:/#

# W1=”A”; W2=”B”; W3=”C”

# WORD=${W1}AA${W2}BB${W3}CC

# echo $WORD

AAABBBCCC

# unset WORD

– $10과 ${10}은 다르다. 왜냐하면 $10은 positional parameter $1값에

   0값이 붙여서 출력되며, ${10}은 positional parameter 10번째의 값을

   나타내기 때문이다.

u        Positional Parameter(위치변수)

shell-script  arg1  arg2  arg3  arg4

$0               $1    $2     $3    $4

Positional Parameter : $1,$2,$3,$4

$0          shell script명을 나타낸다

$1          첫번째 argument를 나타낸다. 즉, arg1

$2          두번째 argument를 나타낸다. 즉, arg2

$*          “arg1 arg2 arg3 arg4 …” 즉,모든 argument와 같다.

$@          “arg1” “arg2” “arg3” “arg4…” 즉,개개의 argument와 같다.

$#          모든 argument의 갯수

$?          마지막으로 수행된 명령어가 return한 값

$$          현재 shell script를 수행하고 있는 shell의 process id(pid)

$!          현재shell에서 수행한 마지막 background의 pid

$_          shell command의 마지막 argument를 가르키며,shell start시에는

            shell의 절대 PATH를 가르킨다.

# set aaa bbb ccc ddd eee fff 

– set명령어를 옵션없이 사용하면 positional parameter를 setting한다.

# echo $0      sh   현재shell를 나타낸다.

# echo $1      aaa

# echo $#      5    $# 은 argument의 개수를 나타낸다.

# echo $*      “aaa bbb ccc ddd eee fff”

# echo $@      “aaa” “bbb” “ccc” “ddd” “eee”

– “$*” 와 “$@” 의 차이점은 $*은 Positional parameter의 모든값을 하나의

  문자열(string)으로 취급하며 $@ 는 string을 개개의 문자열로 취급한다.

# echo $$    7637   : shell의 process id

${parameter}           parameter의 값. 이것은 {}뒤에 붙어있는 문자나

                       숫자,_ 와 같은문자와 함께 사용할 때 필요하다.

${#parameter}          parameter값의 문자수. ${#*}나 ${#@}은 positional

                       parameter의 개수를 나타낸다.

${#identifier[*]}             배열 identifier에서 element의 수를 출력한다.

${parameter:-word}     parameter가 set되고 NOT NULL이면 parameter값을 출력하고,

                       그렇지 않으면 word의 값을 출력한다.

${parameter:+word}     parameter가 set되고 NOT NULL이면 word의 값을 출력하고,

                       그렇지 않으면 아무것도 출력하지 않는다.

${parameter:=word}     parameter가 set되고 NOT NULL이면 parameter의 값을

                       출력하고, 그렇지 않으면 word의 값을 출력하고 parameter에

                       word의 값을 assign한다. Positional parameter는

                       이렇게 setting할 수 없다.

${parameter:?word}     parameter가 set되고 NOT NULL이면 parameter값을

                       출력하고, 그렇지 않으면 word를 출력하고 shell를

                       exit한다. word가 생략되면 화면에 표준출력된다.

# dir1=/home/tmp

# echo ${dir1:-/usr/bin}

/home/tmp

# unset X

# echo ${X:-“X is unset”}

X is unset   : X가 unset또는 null이면 word가 출력된다.

# echo ${dir1:+/usr/bin}

/usr/bin     : dir1이 null이면 아무것도 출력되지 않는다.

# echo ${dir1:=/usr/bin}

/home/tmp    : dir1이 unset되었거나 null이라면 /usr/bin이 출력된다.

# echo ${dir1:?/usr/bin}

/home/tmp

# echo ${#dir1}

10               : /users/tmp 의 총 문자갯수

${parameter#pattern}   pattern이 parameter값의 첫문자와 같으면 그문자를

${parameter##pattern}  포함한 부분은 delete된다. ##은 wild card(*)시 사용함.

   

${parameter%pattern}   pattern이 parameter값을 끝문자와 같으면 그문자를

${parameter%%pattern}  포함한 문자는 delete된다. %%은 wild card(*)시 사용함.

# XX=/a/b/c/d/a/b

# echo ${XX#*a}

/b/c/d/a/b

# echo ${XX##*a}

/b

# echo ${XX%a*}

/a/b/c/d/

# echo ${XX%%a*}

/

# AA=”12345123″

# echo ${AA#1}

2345123

# echo ${AA##*1}

23

# echo ${AA%3}

1234512

# echo ${AA%%3*}

12

# echo ${AA#5}

12345123

# echo ${AA##*5}

123

# echo ${AA##*3*}

# echo ${AA##6*}

12345123

u        Tilde(~) Substitution

만약 user mary의 home directory가 /users/mary라면

# echo $HOME

/users/mary

# echo ~           : ~ 는 user의 home directory를 나타낸다.

/users/mary

# echo $PWD

/users/mary/tmp

# ls ~+/x*         : ~ 다음의 + 는 현재directory 즉, $PWD의 값을 가르킨다.

/users/mary/tmp/x_file1

/users/mary/tmp/x_file2

# echo $OLDPWD

/users/mary/mail

# ls ~-/f*         : ~ 뒤의 – 는 이전 directory 즉, $OLDPWD의 값을 가르킨다.

/users/mary/mail/from.mike 

/users/mary/mail/from.nick

u        Shell Command Grouping

l         ( command )  : subshell grouping

                 shell은 마치 또다른 script를 call한것처럼 subshell

                 환경에서 command를 수행한다.

l         { command ;} : brace grouping

                    shell은 현재의 shell 환경에서 연속해서command를

수행하며 마지막에 반드시 ;(세미콜론)을 써야한다.

# vi test1.sh

#! /usr/bin/sh

# (command)의 Example

A=”aaa”

B=”bbb”

C=”ccc”

( A=”AAA”

B=”BBB”

C=”CCC”

echo “PID $$ :

      $A $B $C” )

echo “PID $$ :

       $A $B $C”

:wq

# sh test1.sh

PID 28999 : AAA BBB CCC

PID 28999 : aaa bbb ccc

# vi test2.sh

#! /usr/bin/sh

# {command;}의 Example

A=”aaa”

B=”bbb”

C=”ccc”

{ A=”AAA”

B=”BBB”

C=”CCC”

echo “PID $$ :

      $A $B $C” ;}

echo “PID $$ :

       $A $B $C”

:wq

# sh test2.sh

PID 28955 : AAA BBB CCC

PID 28955 : AAA BBB CCC

u        Shell Script의 수행

# sh shell_script

# ksh shell_script

# chmod 777 shell_script

# ./shell_scipt

u        Shell Script Comment

l         shell script에서 comment는 첫라인에 # symbol를 넣는다.

l         shell script에서 첫라인의 #! /usr/bin/sh의 의미는 이 shell은

    Posix shell로 수행한다는 의미이다.

u        Input and Output

stdin(0)         standard input으로서 default는 keyboard이며

                 file descriptor값은 0 이다.

stdout(1)        standard output으로서 default는 terminal display이다.

                 file descriptor값은 1 이다.

stderr(2)        standard error로서 default는 terminal displsy이다.

                 file descriptor값은 2 이다.

<word            표준입력(file descriptor 0)으로 word를 사용한다.

>word            표준출력(file descriptor 1)으로 word를 사용하며,

word라는 file이 생성된다.

>|word           >word와 같으며 noclobber옵션이 설정되있어도 무조건 overwrite한다.

>>word           word라는 file이 존재하면 file에 append한다.

없으면 word라는file을 생성한다.

<>word           word를 입력으로 받아서 다시 word라는 file로 출력한다.

<<word           shell prompt에서 word라는 글자를 만날때까지 command를 입력할 수

                 있으며 word라는 글자를 만나면 shell command가 수행된다.

<&숫자           file descriptor 숫자의 file에서 data를 입력받는다.

>&숫자           file descriptor숫자를 가진 file로 출력한다.

<&-              표준입력을 close하여 keyboard로부터 입력받지 못한다.

>&-              표준출력을 close하여 terminal로 출력하지 않는다.

# ftp -n -i << AAA

>open mars

>user root password

>cd /users

>mget *

>close

AAA

#

# vi datafile       : data file작성

aaa

bbb

ccc

:wq

# vi read.sh

exec 5< datafile  : datafile을 file descriptor 5번으로 open한다.

read -u5 X        : 첫라인을 read하여 X변수에 assign한다.

read -u5 Y         : 둘째라인을 read하여 Y변수에 할당.

read -u5 Z        : 셋째라인을 read하여 Z변수에 할당.

exec 5<&-         : file descriptor 5번 file을 close한다.

echo “$X $Y $Z”   : file descriptor은 3-9까지 쓸수있다.

:wq

# sh read.sh

aaa bbb ccc

u        조건 표현식

test 또는 [ … ]             Integer,string.file등에 모두사용(old syntax)

(( … ))              Integer에만 사용(new syntax)

[[ … ]]              string,file에만 사용(new syntax)

l         String 표현식  # man test 참조

   
—————————————————————————-

[ -b file ]            file이 존재하고 block special file이면 참

[ -c file ]            file이 존재하고 character special file이면 참

[ -d file ]            file이 존재하고 directory이면 참

[ -e file ]            file이 존재하면 참

[ -f file ]            file이 존재하고 ordinary file이면 참

[ -g file ]            file이 존재하고 setgid bit가 set되있으면 참

[ -h file ]            file이 존재하고 symbolic link되었으면 참

[ -k file ]            file이 존재하고 sticky bit가 set되었으면 참

[ -p file ]            file이 존재하고 fifo special file또는 pipe이면 참

[ -r file ]            file이 존재하고 readable하면 참

[ -s file ]            file이 존재하고 file size가 0보다 크면 참

[ -u file ]            file이 존재하고 setuid bit가 set되 있으면 참

[ -w file ]            file이 존재하고 writable하면 참

[ -x file ]            file이 존재하고 executable하면 참

[ -L file ]            file이 존재하고 symbolic link이면 참

[ -O file ]            file이 존재하고 user가 effective user id와 같으면 참

[ -G file ]            file이 존재하고 group이 effective group id와 같으면 참

[ -S file ]            file이 존재하고 socket이면 참

—————————————————————————–

[ -n string ]          string의 길이가 non zero면 참

[ -z string ]          string의 길이가 zero이면 참

[ string ]                    string이 not null string이면참

# if [ -f /etc/rc.config ] ; then

# if [ ! -d /usr/bin ] ; then

# if [ -z “$NODENAME” ] ; then

# if [ -x /usr/dt/bin/dtrc ] ; then

# if [[ -n “$NAME” ]] ; then

# if [[ -s /var/spool/lp/pstatus ]] ; then

# if [[ -r /var/run/mrouted.pid ]] ; then

# if [[ -z “$pid” ]] ; then

# if /usr/sbin/envd ; then

# if /sbin/local_is_root ; then

# if [ “$ARRAYMON_PID” ] ; then

# if [ “$START_OV500” ] ; then

[ file1 -nt file2 ]    file1이 존재하고 file2보다 newer이면 참

[ file1 -ot file2 ]    file1이 존재하고 file2보다 older이면 참

[ file1 -ef file2 ]    file1이 존재하고 file2와 equal file이면 참

# if [ /sbin/init.d/spa –nt /sbin/init.d/set_date ] ; then

# if [ /aaa –ot /bbb ] ; then

# if [ /ccc –ef /ddd ] ; then

[ string1 = string2 ]  string1과 string2가 같으면 true

[ string1 = pattern ]  string1과 pattern이 같으면 true

[ string1 != string2 ] string1과 string2가 같지않으면 true

[ string1 != pattern ] string1과 pattern이 같지않으면 true

[ string1 < string2 ]  string1이 string2보다 작으면 true

[ string1 > string2 ]  string1이 string2보다 크면 true

# if [ “$pid” = “” ] ; then

# if [ X$pid != “X” ] ; then

# if [ $HOST != `hostname` ] ; then

# if [ “$MWASTART” > “1” ] ; then

# if [[ $? = 255 ]] ; then

[ exp1 -eq exp2 ]             exp1과 exp2가 같으면 참(equal)

[ exp1 -ne exp2 ]             exp1과 exp2가 같지 않으면 참(not equal)

[ exp1 -lt exp2 ]             exp1이 exp2보다 작으면 참(less than)

[ exp1 -gt exp2 ]             exp1이 exp2보다 크면 참(greater than)

[ exp1 -le exp2 ]             exp1이 exp2보다 작거나 같으면 참(less than or equal)

[ exp1 -ge exp2 ]             exp1이 exp2보다 크거나 같으면 참(greater than or
equal)

# if [ $x –ne 0 ] ; then

# if [ $? –eq 0 ] ; then

# if [ “$RWHOD” –eq 1 ] ; then

# if [[ “$rval” –eq ${EXIT_NA} ]] ; then

# while [ ${CNT} –le ${MAX_NISCHECKS} ] ; then

# if [ $# -ge 0 ] ; then

# if [ “$XX” –gt “$YY” ] ; then

# if [ “$X” –lt 1 ] ; then

# if [ $# -ne 1 ] ; then

# if [ `grep $HOSNAME /etc/mail/sendmail.cw|wc –l` -eq 0 ] ; then

( expression )         expression이 참이면 참

! expression           Binary NOT 연산자

exp –a exp2            Binary AND 연산자, 우선순위가 –o 보다 높음.

exp –o exp2            Binary OR 연산자

exp1 && exp2           exp1과 exp2가 모두 참이면 참

exp1 || exp2           exp1가 참이거나 exp2가 참이면 참

# if [ “$GATED” –eq 0 –a “X$pid” = “X” ] ; then

# if [ “$CRON” –eq 1 –a –x /usr/sbin/cron ] ; then

# if [ “$NIS_DOMAIN” –a –f /usr/bin/domainname ] ; then

# if [ “$NIS_MASTER” –ne 0 –o “$NIS_SLAVE” –ne 0 ] ; then

# if [ “$9” = ‘S’ ] || [ “$9” –lt ‘2’ ] ; then

# if [ “$VTDAEMON_START” –eq 1 ] && [ -x /usr/sbin/vtdaemon ] ;
then

# if [[ -r /usr/sbin/swagentd# ]] && [[ -h /usr/sbin/swagentd ]] ;
then

# if [ $status !=2 –o –z “$DOMAIN” –o –z “$SERVER” ] ; then

# if (( status == 0 )) && [[ -n $PROTO ]] ; then

l         Integer 표현식

(( integer1 == integer2 ))    integer1과 integer2가 같으면 참

(( integer1 != integer2 ))    integer1과 integer2가 같지 않으면 참

(( integer1 < integer2 ))           integer1이 integer2보다 작으면 참

(( integer1 > integer2 ))           integer1이 integer2보다 크면 참

(( integer1 <= integer2 ))    integer1이 integer2보다 작거나 같으면 참

(( integer1 >= integer2 ))    integer1이 integer2보다 크거나 같으면 참

# if (( $? != 0 )) ; then

# while ((n>0))

# if ((n<2) || !length(part[2])) ; then

# if ( $1 != mypid ) ; then

# if (( $1 > $2 )) ; then

3.Shell Programming

u        if 조건문

if 조건문

then

   명령어

[elif 조건문

then

   명령어]

[else

   명령어]

fi

if 조건문; then 명령어; [elif 조건문; then 명령어;] [else 명령어;] fi

:wq# vi if1.sh

X=hello

if [ $X = hello ]

then

   echo “Welcome”

else

   echo “Goodbye”

fi

:wq

# sh if1.sh

Welcome

# vi if2.sh

if [ -f temp ]

then

   mv temp temp1

elif [ -f temp1 ]

then

   mv temp1 temp2

fi

:wq

# sh if2.sh

u        case 조건문

case 변수 in

변수값1|변수값2…)

   명령어;;

변수값3|변수값4…)

   명령어;;

*)

   명령어;;

esac

#  vi case.sh

case $1 in

-d|-r)

        rmdir $dir1

        echo “directory removed” ;;

-o)

        echo “option -o” ;;

*)     

        echo “Invalid option,Try again…” ;;

esac

:wq

# chmod 777 case1.sh

# ./case.sh -o

option -o

u        while 반복문

while 조건문

do

   명령어

done

– 다음은 모두 같은 while문이다.

while [ 1 ]

do

  echo “Test”

done

while true

do

  echo “Test”

done

while [ : ]

do

  echo “Test”

done

while :

do

  echo “Test”

done

# vi while1.sh

count=$(who|grep -v root|wc -l)

while [ “$count” -gt 0 ]

do

   echo “Users still logged in…”

   sleep 1

   count=$(who|grep -v root|wc -l)

done

:wq

# sh while1.sh

# vi while2.sh

# /usr/bin/sh

#

print -n “Enter a value : “

read Value

print “Thank You”

count=0

while [ “$count” -lt “$Value” ]

do

   (( count=count + 1 ))

   print “Still sleeping for the $count th time…”

   sleep 2

done

print “End of $0”

:wq

# sh while2.sh

u        for 반복문

for 변수 [in 변수값1,변수값2,…]

do

   명령어

done

# vi for1.sh

for name in $(cut -d -f1 /etc/passwd)

do

   mailx $name < message.txt

   echo “Mail sent to $name”

done

:wq

# sh for1.sh

# vi for2.sh

if [[ ! -d “$1” ]]

then

   exit 1

fi

filename=$(ls $1)

for onefile in $filename

do

   if [[ -f ${1}/$onefile ]]

   then

      ll ${1}/$onefile

   elif [[ -d ${1}/$onefile ]]

   then

      ll -d ${1}/$onefile

   fi

done

:wq

# sh for2.sh /etc

u        until 반복문

until 조건문

do

   명령어

done

# vi until.sh

count=$(who|grep -v root|wc -l)

until [ “$count” -eq 0 ]

do

   echo “Users still logged in…”

   sleep 1

   count=$(who|grep -v root|wc -l)

done

:wq

# sh until.sh

u        select 반복문

select 변수 [in 변수값1,변수값2,…]

do

   명령어

done

– select문은 PS3 prompt를 사용한다. PS3 shell 변수의 기본값은 #? 이다.

– 변수는 변수값1,변수값2,… 등이 할당된다.

– 입력된 변수의 값의 숫자는 REPLY라는 shell변수에 저장된다.

– exit,return,break 등의 명령어로 반복문을 빠져나올수 있다.

– [in 변수값1,변수값2,…]가 없을경우에는 Positional Parameter를 사용한다.

# vi edit.sh         ### Edit the file ###

select menu in $(ls) “Exit” ; do

   case $menu in

     Exit) exit;;

     “”) echo “Invalid selection. Try again!”;;

     *) cp $menu $menu.bak; vi $menu ;;

   esac ; done

:wq

# vi color.sh

  select color in red blue green

  do

     echo “$color is an $color color”

     echo “$REPLY is a REPLY value”

  done

:wq

# sh color.sh

1)red

2)blue

3)green

#? 1

red is an red color

1 is a PEPLY value

#? 2

blue is an blue color

2 is a REPLY value

#? ^C

#

# vi select.sh

PS3=”Enter your choice =>”

select menu in “full backup”

                  “partial backup”

do

 case $menu in

 “full backup”)

  fbackup –0uf /dev/rmt/0m –i /stand

  echo “Full backup has begun”

  exit 0;;

 “Partial backup”)

fbackup –0uf /dev/rmt/0m -i /opt

echo “Partial Backup has begun”

return;;

 *) echo “$REPLY is an invalid

             option. Try again!”;;

 esac

done

:wq

# sh select.sh

# vi nest.sh

  #### Nested Select Command Example ###

#! /usr/bin/sh

PS3=”Main Choice by number=>”

select menu in “List Files” “Exit”

do

   case $menu in

   “List Files”)

      PS3=”Sub Choice by number=>”

      select ls_option in “Short” “Long” “Main”

      do

         case $ls_option in

          “Short”) lsf;;

           “Long”) ll;;

           “Main”)

               PS3=”Main Choice by number=>”  ## Restore Prompt

               break 1 ;;  ## exit inner loop

           “”) echo “$REPLY is an invalid option. Try again!”;;

         esac

      done ;;

   “Exit”) exit;;

   “”) echo “$REPLY is an invalid option. Try again!”;;

   esac

done

:wq

# sh nest.sh

u        Function(함수)

function 함수명

{

  shell script

}

함수명()

{

  shell script

}

– shell script안에 선언할수도 있고 밖에 선언할수도 있다.

– 함수명이나 argument로 called될수 있다.

– 같은 process를 반복적으로 사용할때 유리하며 debugging하기가 쉽다.

– typeset -xf name 으로 함수명을 export하여 global 함수로 선언할수 있다.

# vi func1.sh

function exef

{

   if [ -x $1 ]

   then

      echo “$1 is executable”

   fi

}

for file in `ls`

do

   exef $file

done

:wq

# sh func1.sh

# vi func2.sh

Uppercase()

{

   echo $* | tr “[a-z]””[A-Z”]”

}

print -n “Enter in a string:”

read string

upper_string=$(Uppercase $string)

echo “The uppercase string is: $upper_string”

:wq

# sh func2.sh

# vi func3.sh       : Recursive Fuction

bottom_up

{

   typeset SAVEPWD

   echo “\nDirectory being listed is: $PWD\n”

   lsf

   if [ “$PWD” != “/” ]

   then

      SAVEPWD=$PWD

      cd ..

      bottom_up

      cd $SAVEPWD

   else

      echo “That’s the end!”

   fi

}

:wq

# sh func3.sh

u        Array(배열)

– shell script에서 사용할수 있는 배열은 1차원배열이다.

– 배열요소(element)는 최대 512-1024까지 쓸수 있다.

– 배열요소는 [0]부터 [1023]까지 쓸수 있다.

– Array subscript인 [N]에서 N은 integer또는 integer expression을 쓸수 있다.

# X[0]=first

# X[1]=second

# X[2]=third

# echo ${X[1]}

second

# echo ${X}         : ${X}는 ${X[0]}과 같음

first

# echo ${X[*]}             : ‘*’나 ‘@’는 모든 요소를 가르킴

first second third

# echo ${#X[*]}

3

# i=3

# X[2*(i+1)]=10

# print ${X[8]

10

# set -A YY 100 200 300    : set -A는 변수를 배열로 선언한다.

# print ${YY[0]} ${YY[1]} ${YY[2]}

100 200 300

# set +A YY 150

# print ${YY[@]}

150 200 300

4.Shell Command

u        : 명령어

– ‘:’ 명령어는 아무것도 수행하지 않으며, 어떤 영향도 미치지 않는다. ‘0’값이 return됨.

# vi xx.sh

if [ -f /opt ]; then

   ls

else

   :            아무것도 수행하지 않는다.

fi

:wq

u        . 명령어

# . /etc/profile

– /etc/profile이라는 프로그램을 수행한다. 이는 sh나 ksh처럼 또하나의 shell을 fork하여

  프로그램을 수행하지 않으며 이 프로그램은 수행가능한 permission이 없어도 된다.

  즉 이 파일은 ‘x’ permission이 없어도 된다.

u        alias 명령어

alias [-x] [ name[=value] … ]

# alias                             : 현재 setting된 모든 alias를 display

# alias a=alias

# a x=lsf

# alias i=’

> echo Users logged in are:

> who|sort

> echo I am `whoami`’

# i                                  : alias문을 수행한다.

# unalias i                        : alias변수 i를 unsetting한다.

# unalias -a                       : shell command에서 typing한 모든

                                        alias를 해제한다.

# alias -x who=’who|sort’       : Korn shell에서 who를 export하여

                                        subshell에서도 사용가능하다.

u        break 명령어

break [n]

– for,while,until,select문과 같은 반복문에서 exit할 때 사용한다.

– n을 쓰면 n레벨만큼 loop를 exit한다.

# vi break.sh

for file in x y z none

do

   if [ -x $file ]; then

      echo $file

      break

   fi

done

:wq

u        command 명령어

command [arg …]

– argument를 command로서 취급한다.

# command lsf       : lsf를 command로 사용한다.

# command aaa       : aaa를 command로 사용한다.

u        continue 명령어

continue [n]

– for,while,until,select문과 같은 반복문에서 continue이하의 문을 수행하지 않고

다시 시작한다.

    – n을 쓰면 n번째 반복문을 다시 시작한다.

# vi con.sh

for file in x y z

do

   if [ -x $file ]; then

      continue

      echo “$file is executable”

   fi

   echo $file is not executable

done

:wq

u        echo 명령어

echo [arg …]

# echo ‘This is a’ $var ‘example.’

# echo “This is a $var example.”

# echo “Enter your user name: \c”

> read user

> echo ‘User is’ $user

echo 에서 Escape Character

\b     backspace

\c     continue line. new line을

       하지 않고 계속 붙여서 print한다

\f     form feed

\n     new line

\r     carriage return

\t     tab

\v     vertival tab

\\     backslash

u        eval 명령어

eval [arg …]

– argument를 input으로 받아서 명령어로 수행하며 argument는 command나 shell

  script가 될수 있다.

# cmd=’ps -ef > ps.out’

# eval $cmd

# eval “grep jones $file|set|echo $1 $2 $3”

u        exec 명령어

exec [arg …]

– 새로운 process나 subshell을 만들어서 argument를 수행하지 않고 현재 shell로

  명령어를 바로 수행한다.

# exec 3< file          file desciptor number 3으로 file을 open한다.

# ecec 2> /dev/null     표준에러를 /dev/null로 출력한다.

u        expr 명령어         # man expr 참조

expr expression {+,-,\*,/} expression

expr expression {=,\>,\>=,\<,\<=,!=} expression

expr string1 : string2

# a=15

# expr $a + 5

20

# count=`expr $count + 5`

# A=batman

# expr substr $A 1 3

bat

# expr index $A m

4

u        fc 명령어

fc [-r] [-e example] [first [last]]

fc –l [-nr] [first [last]]

fc –s [old=new] [first]

fc –e – [old=new] [command]

– fc command는 history file을 list하거나 history file에서 command를 edit할 수있다.

# fc –l            : history file의 내용을 display한다.

# fc –l 20 25

# fc –l 10

# fc –e vi 15 20

# fc –e –          : 방금 실행한 command를 다시 실행한다. # r 명령과 같다.

# fc –e – ls=cd  

u        let 명령어

let “expression”

(( expression ))

– let는 산술 표현을 가능하게 하며 long integer 계산을 한다.

Operator

Description

!

/  %

+  –

<  <=  >  >=

==  !=

=

unary minus

logical negation

곱하기,나누기,몫

더하기,빼기

비교

같다,같지 않다

변수 할당

# x=10

# y=2

# let x=x+2

# echo $x

12

# let “x=x/(y+1)”

# echo $x

4

# (( x=x+1 ))

# echo $x

5

# x=12

# let “x<10”

# echo $?

1

# (( x > 10 ))

# echo $?

0

# if (( x > 10 ))

>then echo x greater

>else echo x not greater

>fi

x greater

u        read 명령어

read [-r] name…        : POSIX Shell only

read [-prsu] [name]    : Korn Shell only

-r          라인연속으로 쓰인 라인끝의 \를 해석하지 않는다.

-un         file descriptor n 으로부터 input을 read한다.

# vi read.sh

  while read -r xx yy

  do

     printf “%s %s \n” “$yy” “$xx”

done < input_file

:wq

u        return 명령어

return [n]

– 함수의 실행을 마치고 calling shell script에게 exit status n을 return한다.

– n이 없으면 return status는 함수의 마지막 command의 값이다.

– return이 함수의 밖에서 수행되면 exit로서 실행된다.

# vi return.sh

  search()

  {

     if grep xxx “$1” > /dev/null 2>&1

     then return 1

     else return 2

     fi

  }

:wq

# sh return.sh filename

u      set 명령어

l         Positional Parameter값 setting

# set spring summer fall winter

# echo $3

fall

# echo $*

spring summer fall winter

l         Positional Parameter Sorting

# set third first second

# echo $1 $2 $3

third first second

# set –s               : 값을 lexical order로 sorting함

# echo $1 $2 $3

first second third

# set +s            : unsetting

option         option-name meaning

——————————————————————————–

set –a         allexport   모든 parameter가 자동으로 export됨. == set -o
allexport

set -C         noclobber   #date>XX시 >로 overwrite하지못하게 함. date>|XX로는
가능

set –e         errexit     shell command fail시 즉시 logout또는 shell을 exit함

set –f         noglob             # ls * 시wild card문자를 인식못함

set –h         trackall   

set –k         keyword    

set –m         monitor     Background jogs이 각각다른 process group에서 수행되고

                           작업이 끝나면 message를 report함

set –o                     set –o monitor와 같이 option-name에 붙여서 옵션을

                           setting함

set –s                     positional parameter를 sort함

set –t                     shell을 exit한후에 command를 수행함

set –u         nounset     substituting시 unset parameter를 error로 취급함

set –v         verbose     command를 display한후 command 수행

set –x         xtrace             command수행시 command와 argument까지 print함.

                           shell script의 debug mode로 사용함.

              

set                        현재 setting된 모든 shell variable을 list함

set –                      -x와 –v option을 turn off하고 flag에 대한 argument

                           검사를 하지 않음

set —                     옵션의 어떤 변화도 하지못하게 함. # set — -;echo $1

                                      file명으로 시작하는 file을 rm할 경우 # set — -;rm
–aaa

# set –o ignoreeof          : ignoreeof라는 옵션을 turn on

# set +o vi                : vi의 옵션을 turn off

# set –o noglob            : noglob옵션을 turn on 시키고 wild card인

                                    *,[],-,!,? 등을 shell이 해석하지 못하게함

# set –o noexec            : shell의 syntax error를 check하기위해 사용.

                             이 옵션은 interactive shell에서는 사용되지

                                    않으며 shell script에서만 수행됨.

                             noexec 옵션은 실제로 shell을 수행하지 않으면서

                                       shell의 syntax error만을 check하는
명령어다.

# vi set1.sh

  set –o noexec

  echo “This is test

  ls

  cp /aaa /bbb

:wq

# ksh set1.sh

set1.sh: syntax error at line 2 : ‘”‘ unmatched

# vi set2.sh

  set –x

  ls

  echo “The Test”

  set +x

  lsf

:wq

# sh set2.sh

u        shift 명령어

shift [n]

shift command는 positional parameter($1,$2,$3..)의 내용을 왼쪽순으로 move한다.

# vi shift1.sh

  yflag=0

  zopt=””

  for arg in “$@”

  do

     if [ “x$arg” = x-y ]

     then

        yflag=1

        shift

     else

       zopt=”$2″

       shift 2

     fi

  done

:wq

u        trap 명령어

trap [command] [signal]

– signal 값은 # kill –l또는 # man kill 명령어로 볼수 있음.

# trap “echo ‘Command Failed'” 2

                       : ^C(interupt)를 치면 echo 문장이 수행됨.

# trap              : trap 명령을 수행한후 옵션이 없이 trap명령을 수행하면 현재

                    setting된 모든 trap내용을 보여줌

# trap “” 1 2 3

                       : 1}HUP 2)INT 3)QUIT가 입력되도 무시하라.

# trap “echo logout” 0

                       : signal이 ‘0’ 이면 NULL signal로서

                         shell에서 exit할때 command가 수행된다.

u      typeset 명령어

typeset [-][+]옵션  변수명[=변수값]

option      meaning

—————————————————————————–

[-]         변수명의 속성을 setting

[+]         변수명의 속성을 turn off

-Ln         왼쪽의 공백을 제거하고 왼쪽에서 n숫자만큼 cut

-Rn         왼쪽에 공백을 채우고 오른쪽에서 n숫자만큼 cut

-Z          오른쪽으로 shift하고, 첫번째 문자가 숫자이고 –L옵션과 같이

            쓰지 않았으면 왼쪽에 숫자0을 채움

-i          변수명을 integer로 선언

-f          변수명이 아니라 함수명으로 변수를 선언

-l          모든 영문대문자를 소문자로 변환

-u          모든 소문자를 대문자로 변환

-r          변수를 read-only로 만듬,즉 변수를 상수로 만듬

-x          변수를 export함, 즉 변수를 전역변수로 만듬

—————————————————————————–

# typeset

현재 setting되어있는 변수의 data type을 보여줌

# typeset AA

AA변수를 string변수로 선언,또한 함수내에서 Local변수 즉 지역변수로 선언

하지만, shell에서 변수는 default로 string data type임

# DATA=”Today we had very HOT weather”

# typeset –u DATA

# echo $DATA

TODAY WE HAD VERY HOT WEATHER

# typeset +u DATA : DATA변수의 속성을 turn off 

# DATA=”as of the “${DATA}

# echo $DATA

as of the TODAY WE HAD VERY HOT WEATHER

# AAA=123456789

# typeset –L3 AAA

# echo $AAA

123

# typeset –LZ X=00005

# print $X

5

# typeset –i X        : 변수X를  integer로 선언 # integer X와 같음

# typeset –i2 X     : 변수X를 2진수로 선언

# typeset –i8 X     : 변수X를 8진수로 선언

# typeset –i10 X    : 변수X를 10진수로 선언

# typeset –i16 X    : 변수X를 16진수로 선언

# typeset -r Y=123  : 변수Y를 readonly변수로 선언 # readonly Y=123과 같음

# typeset -f        : 모든함수와 그 값을 display함

# typeset -xf       : export된 모든함수와 그 값을 display함

# typeset -xf XX    : 함수명 XX를 export하여 global function으로 선언함

u        ulimit 명령어

ulimit  [-f] [n]

– ulimit command는 child process나 subprocess에 의해 사용된는 resources를 제한한다.

# ulimit               : 현재 limit값을 보여준다

# ulimit –f 1000       : 현재process나 향후 process가 write할 수 있는

                          file size를 1000 block(1000*512 byte)으로 제한한다.

# ulimit –f unlimited : child process가 생성할 수 있는 size의 제한을 없앤다.

5.Regular Expression(정규 수식)

u        Pattern Matching과 Regular Expression의 비교 – # man 5 regexp참조

Pattern Matching

Regular Expression

– POSIX shell에서 사용

– file name생성과 case문에서 사용

– UNIX command와 Text Editor에서 사용

  (ed,vi,ex,sed,awk,expr,grep)

– file name을 match한다

– character string을 match한다

– file name을 substitute한다

– string을 search해서 substitute한다

– 사용되는 특수문자

  ?,  *,  [ – ],  !

– 사용되는 특수문자

  .,  [],  -,  ^,  $,  *

u        하나의 문자와 Match – .(dot)

A.          : AB,Ab,AA,A9등과 같이 A다음에오는 어느한문자와 match

…         : 연속된 3문자와 match

# man 5 regexp|col -b|expand > regexp.man

# grep ‘RE.’ regexp.man       : RE다음에오는 어느한문자와 Match되는 라인만 출력

u        문자의 시작과 Match – ^

^abc        : 첫문자가 abc로 시작되는 문자와 match. abc,abcabc,abcdef등과 match

^C          : 문자의 시작에서 C와 match

^C$         : 하나의 문자 C와 match

^.$         : 하나의 문자로만 구성된 문자와 match

^[ABC]      : 첫문자가 ABC로 시작되는 문자와 match

u        문자의 끝과 Match – $

abc$        : 끝문자가 abc로 끝나는 문자와 match. defgabc,cccabc,abc등과 match

^…$       : 3개의 문자로만 구성된 문자와 match

\.$         : 문자의 끝에서 마침표(.)과 match

\*$         : 문자의 끝에서 (*)와 match

u        문자 Match – []

[Tt]he      : The나 the라는 글자를 search

h[iau]t     : hit,hat,hut의 글자와 match

[ABC]       : A,B,C를 포함하는 문자와 match

u        범위를 포함하는 문자와 Match – [ – ]

[a-z]       : 소문자 a부터 z까지 어느문자와도 match

[0-9]        : 0-9까지 어떤 하나의 숫자와 match

[0-57]      : 0,1,2,3,4,5,7과 match

[a-c5-8X-Z] : a,b,c,5,6,7,8,X,Y,Z중 하나의 문자와 match

[0-3-]      : 0,1,2,3,-와 match

u        Complemented문자 Match – [^  ]

[^ ]        : 공백이 아닌 한문자와 match

[^0-9]      : 0-9까지 숫자가 아닌 하나의 모든문자와 match

[^a-zA-Z]   : 영문 알파벳이 아닌 문자나 숫자와 match

[012^]      : 0,1,2,^와 match

^[^a-z]$    : 소문자을 제외한 나머지 문자중 하나와 match

# man 5 regexp|col -b|expand > regexp.man

# grep ‘^$’ regexp.man|wc -l         : 공백라인수를 출력한다.

# TMOUNT=`/sbin/mount | grep ‘^/tmp(/| )’ | wc -l`

# grep -q -e “^/usr/bin$” -e “^/usr/bin:” -e “:/usr/bin:”\

         -e “:/usr/bin$” /etc/PATH

u        Null 또는 여러 같은문자와 Match – *,+,?

B*          : Null문자,B,BB,BBB…등과 match

AB*C        : AC,ABC,ABBC…등과 match

A+          : A,AA,AAA…등과 match

AB+C        : ABC,ABBC,ABBBC…등과 match

A?          : Null문자 또는 A와 match

AB?C        : AC,ABC와 match

[A-Z]+      : 하나이상의 대문자와 match

(AB)        : AB문자와 match

(AB)+C      : ABC,ABABC,ABABABC…등과 match

AB.*XYZ     : ABXYZ,ABCXYZ,ABCCCCXYZ…등과 match

u        특수문자 Match – \

\*          : 특수문자 *와 match

\$          : 특수문자 $와 match

\\          : 특수문자 \와 match

\\\\\.\*$   : 문자의 끝에서 \\.* 와 match

u        Subexpression – \( … \)

– \(…\)구문을 사용한다.

– subexpression과 match하는 문자를 recall하기위해 ‘\숫자’를 사용한다.

– ‘\숫자’ 는 1-9까지 쓸수있다.

– \1 은 1번째 subexpression,\2 는 2번째 subexpression을 나타낸다.

# who

root       console      Oct 23 13:01

root       ttyp1        Oct 27 12:45

root       pts/0        Oct 22 09:03

# who|sed ‘s/\([^ ][^ ]*\)[^A-Z][^A-Z]*\(.*\)/\2–>\1/’

Oct 23 13:01–>root

Oct 27 12:45–>root

Oct 22 09:03–>root

– 첫번째 /\([^ ][^ ]*\) 는 공백이 아닌 하나이상의 문자와 match하며 뒷부분의

  \1 의 값과 같다.즉, 여기서는 username root를 가르킨다.

– 두번째 \(.*\) 는 최초로 대문자로 시작되는 문자와 match하며 뒷부분의

  \2 의 값과 같다. 여기서는 Oct를 가르킨다.

6.Sed(Stream Editor)

u        sed 형식

sed [-n] command input_file…

sed [-n] [-e command]… [-f script_file]… [input_file…]

-n          화면에 display하지 않는다. 단  p명령어일경우는 화면에 display한다.

            -n옵션은 -e나 -f옵션중 하나와 같이 사용할수 있다.

-e command  command를 editing하며, input file이 없으면 표준입력이 사용된다.

-f script   input file에서 editing command의 script file을 수행한다.

– sed는 입력파일로부터 한라인씩 data를 read한다.

– sed는 default로 화면에 출력을 하며 input file을 modify하지 않는다.

# sed “s/UNIX/Unix/g” file1 > file2.new

# sed -e “s/Miss/Ms/g” -e “s/Mrs/Ms/g” file2

# sed -n “1,10p” file2

# cat script

1,10p

# sed -n -f script file2

u        s(substitute)

[address [,address]] s/string_old/string_new/[flag]

flag        meaning

g           global substitution(전라인을 모두바꾼다)

p           print line

w file      file로 write한다

# sed “s/[Cc]omputer/COMPUTER/g” file1

# sed -e “1,5s/abc/xyz/” -e ‘s/kbs/mbc/’ file1 > file2

# sed “/abcde/s/ab/AB/g” file1

# sed -e ‘s/abc/xyz/w file2’ file1

# sed “3s/the/xyz/g” file1

# sed ‘3s/^the /xyz/’ file1

# sed -e “/the/s/ for /xyz/g

# cat file1| sed “/the/s/ for /xyz/gw file2

# sed “1,8s/aaa/bbb/g” file1 > file2

# sed “/^5/,/^15/s/from/FROM/g”

# sed -e “/^The first time/,/^End of file/s/lsf/ll/g”

# sed “1,$s/\/usr\/bin/\/sbin\/bin/g”

u        d(delete)

# sed “1,10d” fileA

   – fileA에서 1-10라인까지 delete한다.

# sed “/^From/!d” mbox

   – mbox file에서 From으로 시작되는 라인만 제외하고 모두 delete한다.

u        p(print),l(list),=,q(quit),r(read),w(write)

p           standard output에 print한다. -n옵션과 함께써도 print된다.

l           nonprinting문자도 같이 표준출력한다.

=           address 라인의 라인번호를 표준출력한다.

q           현재라인을 출력하고 sed를 종료한다.

r file      file의 내용을 read하여 표준출력한다.

w file      file에 address라인을 write또는 append한다.

# vi cap

   One potato, teo potato,

   three potato, four.

   Five potato, six potato,

   seven potato, more.

:wq

# sed -n “1,2p” cap

One potato, two potato,

three potato, four.

# sed -e “q” cap

One potato, teo potato,

# sed -e “/\./=” -e ” /[A-Z]/w file1″ cap

One potato, teo potato,

2

three potato, four.

Five potato, six potato,

4

seven potato, more.

# killproc() {

      for x in “$@”

      do

         pid=`ps -e |grep “$x” |sed -e ‘s/^  *//’ -e ‘s/ .*//’`

         [ ! –z “$pid” ] && echo killing $x && kill $pid
&

      done

  }

# findproc() {

    pid=`ps –e |grep “$1” |sed -e ‘s/^  *//’ -e ‘s/ .*//’`

    echo $pid

  }

# killproc() {           

      echo stopping $1

      pid=`/usr/bin/ps -e |

            /usr/bin/grep “$1” |

            /usr/bin/sed -e ‘s/^  *//’ -e ‘s/ .*//’`

            [ “$pid” != “” ] && kill $pid

  }

# if [ “$RWHOD” –ne 1 ]; then

      rval=2

  else

      pid=`ps -el | awk ‘( ($NF ~ /rwhod/) && ($4 != mypid)
&&

           ($5 != mypid)) { print $4 }’ mypid=$$ `

      if [ “X$pid” != “X” ]; then

         if kill $pid; then

            echo “rwhod stopped”

         else

            rval=1

            echo “Unable to stop rwhod”

         fi

      fi

  fi

#

#

#

# ARRAYMON_PID=`ps -ef | awk ‘$0 ~ /.*arraymon*/ && $0 !~
/.*awk.*/

                  { print $2 }’`

  if [ “$ARRAYMON_PID” ]

  then

     echo “Killing disk array monitor daemon.”

     kill -9 $ARRAYMON_PID

     sleep 2

     ARRAYMON_PID=`ps -ef | awk ‘$0 ~ /.*arraymon*/ && $0 !~
/.*awk.*/

                     { print $2 }’`

     if [ “$ARRAYMON_PID” ]

     then

       echo “ERROR:  Could not kill ${ARRAY_MONITOR_DAEMON}”

     fi

  fi

#

7.Shell Program 예제

-shell script를 위한 data file은 다음과 같다.

# vi data

  100 200 300 400

  500 600 700 800

  900 1000 1100 1200

  1300 1400 1500 1600

  1200 800 400 0

:wq

# vi exp1.sh

if [[ ! -f “$1” ]]

then

   echo “${0##*/}”

   exit 1

else

   filename=$1

fi

exec 3< $filename : file descriptor 3으로 filename를 open

typeset -i II=0   : XX를 integer로 선언

while read -u3 AA[0] AA[[1] AA[2] AA[3]

do

   for II in 0 1 2 3

   do

      (( total[II]=${total[II]} + ${AA[II]} ))

   done

print “Subtotal : “

print ${total[*]}

done

print “Total for the four columns are : “

print ${total[@]}

:wq

# sh exp1.sh

#!/usr/bin/sh

######################## /etc/profile ##########################  

trap “” 1 2 3                   

PATH=/usr/bin:/usr/ccs/bin:/usr/contrib/bin

MANPATH=/usr/share/man:/usr/contrib/man:/usr/local/man

if [ ! -d /usr/sbin ]

then

   PATH=$PATH:/sbin

else

   if [ -r /etc/PATH ]

   then

      grep -q -e “^/usr/bin$” -e “^/usr/bin:” -e “:/usr/bin:”\

                -e “:/usr/bin$” /etc/PATH

      if [ $? -eq 0 ]

      then

         PATH=`cat /etc/PATH`

      else

         PATH=$PATH:`cat /etc/PATH`

      fi

   fi

fi

export PATH

if [ -r /etc/MANPATH ]

then

   MANPATH=`cat /etc/MANPATH`

fi

export MANPATH

if [ -r /etc/TIMEZONE ]

then

   . /etc/TIMEZONE 

else

   TZ=MST7MDT       

   export TZ

fi

if [ ! “$VUE” ]; then

   if [ “$TERM” = “” -o “$TERM” = “unknown” -o “$TERM” = “dialup”  \

                         -o “$TERM” = “network” ]

   then

      eval `ttytype -s -a`

   fi

   export TERM

   if [ “$ERASE” = “” ]

   then

      ERASE=”^H”

      export ERASE

   fi

   stty erase $ERASE

   trap “echo logout” 0

   cat /etc/copyright

   if [ -r /etc/motd ]

   then

      cat /etc/motd

   fi

   if [ -f /usr/bin/mail ]

   then

      if mail –e

      then echo “You have mail.”

      fi

   fi

   if [ -f /usr/bin/news ]

   then news –n

   fi

   if [ -r /tmp/changetape ]

   then

      echo “\007\nYou are the first to log in since backup:”

      echo “Please change the backup tape.\n”

      rm -f /tmp/changetape

   fi

fi

trap 1 2 3

###################### The End ##########################

#!/usr/bin/sh

############# /.profile ################  

set +u

PATH=/usr/sbin:$PATH:/sbin:/home/root

if [ ! “$VUE” ]; then

   if [ “$TERM” = “” ]

   then

      eval ` tset -s -Q -m ‘:?hp’ `

   else

      eval ` tset -s -Q `

   fi

   stty erase “^H” kill “^U” intr “^C” eof “^D” susp “^Z”

   stty hupcl ixon ixoff

   tabs

   echo

   echo “Value of TERM has been set to \”$TERM\”. “

   export TERM

   EDITOR=vi

   export EDITOR

fi

set –u

trap “echo ‘logout root'” 0

MAIL=/var/mail/root

echo “WARNING:  YOU ARE SUPERUSER !!\n”

export PS1=`hostname`’:$PWD# ‘

############################# The End ##############################

#!/sbin/sh

######################## /sbin/init.d/inetd #######################

PATH=/sbin:/usr/sbin:/usr/bin

export PATH

rval=0

set_return() {

        x=$?

        if [ $x -ne 0 ]; then

                echo “EXIT CODE: $x”

                rval=1  # always 1 so that 2 can be used for other
reasons

        fi

}

case “$1” in

start_msg)

   echo “Start Internet services  daemon” ;;

stop_msg)

   echo “Stopping Internet services daemon” ;;

‘start’)

   if [ -f /etc/rc.config ]; then

      . /etc/rc.config

   else

      echo “ERROR: /etc/rc.config defaults file MISSING”

   fi

   mask=`umask`

   umask 000

   [ -x /usr/sbin/inetd ] && /usr/sbin/inetd $INETD_ARGS

   if [ $? -eq 0 ]; then

      echo “Internet Services started”

   else

      echo “Unable to start Internet Services”

   fi

   umask $mask

   ;;

‘stop’)

   if [ -f /etc/rc.config ]; then

      . /etc/rc.config

   else

      echo “ERROR: /etc/rc.config defaults file MISSING”

   fi

   /usr/sbin/inetd -k

   set_return

   if [ $rval -eq 0 ]; then

      echo “Internet Services stopped”

   else

      echo “Unable to stop Internet Services”

   fi

   ;;

*)

   echo “usage: $0 {start|stop}”

   rval=1

   ;;

esac

exit $rval

############################ The End ##############################3

#!/sbin/sh

############# /sbin/rc ################      

arg=$1

arg2=$2

PATH=/sbin

export PATH

/sbin/stty clocal icanon echo opost onlcr ixon icrnl ignpar 2>
/dev/null

umask 022

get_scripts() {

   state=$1

   mode=$2

   dir=/sbin/rc${state}.d

   ls $dir 2>/dev/null |

   while read name

   do

      case $name in

      ${mode}*)

         path=$dir/$name

         if [ “$mode” = “S” ]; then

            desc=`$path start_msg`

         elif [ “$mode” = “K” ]; then

            desc=`$path stop_msg`

         fi

         echo $path $desc

     esac

  done

}

if [ -f /sbin/rc.utils ]; then

   . /sbin/rc.utils

else

   init_list()

   {

      echo $1

   }

   add_list()

   {

      eval $1

   }

   run_list()

   {

      :

   }

fi

# If /etc/rc.config contains default information (first boot),

# /sbin/auto_parms will invoke /sbin/set_parms to remedy the situation.

# For 10.0 release, the default HOSTNAME is unset or an empty string.

# Assume a timezone if /etc/TIMEZONE does not exist.

TZ=EST5EDT

if [ -f /etc/rc.config ]; then

   . /etc/rc.config

   if [ -x /sbin/auto_parms ]; then

      /sbin/auto_parms

   else

      echo “\nWARNING: /sbin/auto_parms does not exist”

      echo “DHCP invocation skipped.”

   fi

else

   echo “\nWARNING: /etc/rc.config does not exist”

   echo “System name not set, default $TZ assumed.”

fi

export TZ

# Set runlevel information

set `who -r` x

new=$7         # new run level

old=$9         # previous run level

# Check to see if we are run from /etc/inittab, or from the command line.

# If run from the command line, set the old run-level to the new
run-level.

if [ $PPID != 1 ]; then

   old=$new

   # If the new run-level was specified on the command line,go to that
state

   # instead.

   if [[ -n $arg2 ]]; then

      new=$arg2

   fi

fi

if [ “$new” = S ]; then

   new=0

   tosingle=1

else

   tosingle=0

fi

BOOT=0

if [ “$old” = S ]; then

   old=0

   BOOT=1

fi

# Process scripts

found=0

if [ “$new” -gt “$old” ]; then

   # new run level is higher than old, so run start scripts in

   # all intermediate run levels and in new run level.

   if [ $BOOT = 1 ]; then

      init_list “HP-UX Start-up in progress”

   else

      init_list “Transition to run-level $new in progress”

   fi

   typeset -i lvl=$old

   lvl=lvl+1

   while [ $lvl -le “$new” ]; do

      get_scripts $lvl S |

      while read name descrip; do

         if [ -s “$name” ]; then

            add_list “$name start” “$descrip”

            found=1

         fi

      done

      lvl=lvl+1

   done

elif [ “$new” -lt “$old” ]; then

   # new run level is lower than old level, so run kill scripts

   # in all intermediate levels and in new level.

   if [ “$new” = 0 ]; then

      init_list “System shutdown in progress”

   else

      init_list “Transition to run-level $new in progress”

   fi

   typeset -i lvl=$old

   lvl=lvl-1

   while [ $lvl -ge “$new” ]; do

      get_scripts $lvl K |

      while read name descrip; do

         if [ -s “$name” ]; then

            add_list “$name stop” “$descrip”

            found=1

         fi

      done

      lvl=lvl-1

   done

   # If we’re ending up in state 0 or S, run the start scripts for

   # that state.

   if [ “$new” = 0 ]; then

      get_scripts 0 S |

      while read name descrip; do

         if [ -s “$name” ]; then

            add_list “$name start” “$descrip”

            found=1

         fi

      done

   fi

else

   # old and new run levels are the same.  Assume that execution

   # is from the command line and run start scripts for the current

   # run level

   init_list “Starting subsystems for run-level $new”

   get_scripts ${new} S |

   while read name descrip; do

      if [ -s “$name” ]; then

         add_list “$name start” “$descrip”

         found=1

      fi

   done

fi

if [ $found = 1 ]; then

   if [ “$BOOT” = 1 ]; then

      run_list boot

   else

      run_list

   fi

fi

if [ “$new” = 0 ]; then

   case $arg in

   “shutdown”)

      exec /sbin/sh

      ;;

   “reboot”)

      /sbin/reboot

      ;;

   “off”)

      /sbin/reboot -h

      ;;

   esac

   #If transitioned to real state 0 (that is, not state S) via init,
halt.

   if [[ $PPID -eq 1 && “$tosingle” -ne 1 ]]; then

      /sbin/reboot -h

   fi

fi

# Output message to indicate completion

echo

if [ $BOOT = 1 ]; then

   echo “The system is ready.”

else

   echo “Transition to run-level $new is complete.”

fi

############################## The End #################################3

#!/sbin/sh

##################### /sbin/init.d/net ##########################

#

# net:  configure lan interface(s) at initialization time.

# /etc/rc.config.d/netconf defines the configuration parameters:

#

# INTERFACE_NAME[i]:      network interface name (e.g., lan0)

# IP_ADDRESS[i]:          IP address of your system in decimal dot format

# SUBNET_NETMASK[i]:     subnetwork mask in decimal dot format

# BROADCAST_ADDRESS[i]:  broadcast address (other than default) in
decimal

#                             format

# LANCONFIG_ARGS[i]:      lanconfig(1m) options (e.g., ieee, ether)

# LOOPBACK_ADDRESS:       loopback address (always 127.0.0.1)

#

# ROUTE_DESTINATION[i]:  route destination

# ROUTE_MASK[i]:       subnet mask

# ROUTE_GATEWAY[i]:       local or remote IP address of gateway

# ROUTE_COUNT[i]:         zero for local gateway, one for remote gateway

# ROUTE_ARGS[i]:          route command options and arguments

#

###########################################################################

set +u  

export PATH=/sbin:/usr/sbin:$PATH

NETCONF=/etc/rc.config.d/netconf

NETSTAT_DATA=/var/adm/netstat_data

OKAY=0

ERROR=1

WARNING=2

# $1 = name of array

# return highest array element index in env; return -1 if no elements

function maxindex {

   # find only lines that start with “var[…]=”, grab only the number

   # between “[…]”, and print only the last one.

   # we would like to use `sed` as follows:

   #    typeset i=$(set | sed -n ‘s/^’$1’\[\([[:digit:]]\{1,\}\)\]=.*$/\1/p’

   #                | tail -1)

   # but it is not guaranteed to be in a mounted file system at this
time.

   typeset line

   typeset i=-1

   set | while read line; do

      # strip “var[” and “]=…”, leaving only number between “[…]”

      line=${line#*$1\[}

      line=${line%%\]=*}

      # if line is all digits, we found “var[…]=…”,

      # and line is string between “[…]”

      if [[ -n $line && -z ${line##*([[:digit:]])} ]]; then

         i=$line

      fi

   done

   print — $i

   return 0

}

##########

#  main   #

##########

case $1 in

start_msg)

   print “Configure LAN interfaces”

   exit $OKAY

   ;;

stop_msg)

   print “Unconfigure LAN interfaces”

   exit $OKAY

   ;;

stop)

   exit $OKAY

   ;;

start)

   ;;  # fall through

*)

   print “USAGE: $0 {start_msg | stop_msg | start | stop}” >&2

   exit $ERROR

   ;;

esac

###########

#  start  #

###########

# Remove the existing /var/adm/netstat_data file.  The first time

# netstat is executed, a new /var/adm/netstat_data file will be

# created.

rm -f $NETSTAT_DATA

# Get actual configuration

if [[ -f $NETCONF ]]; then

   . $NETCONF               # display any errors

   if (($? != 0)); then

      # NB: this is not working as expected:  status is not propagated!

      print “ERROR:   Incorrect data in the file $NETCONF.” >&2

      exit $ERROR

   fi

else

   print “ERROR:   Missing the file $NETCONF.” >&2

   exit $ERROR

fi

rval=$OKAY

# Do ifconfig and lanconfig commands for each interface

# `foo=$(print $foo)` collapses whitespace, remove surrounding whitespace

# We can have __fewer__ IP_ADDRESSes than INTERFACE_NAMEs (interfaces to
be

# ignore).  We can also have __fewer__ SUBNET_MASKs, BROADCAST_ADDRESSes
and

# LANCONFIG_ARGS (defaulted).  But we cannot have __more__.

# sanity check

nIF=$(maxindex INTERFACE_NAME)

if (($(maxindex IP_ADDRESS) > nIF)) || \

   (($(maxindex SUBNET_MASK) > nIF)) || \

   (($(maxindex BROADCAST_ADDRESS) > nIF)) || \

   (($(maxindex LANCONFIG_ARGS) > nIF))

then

   print “WARNING: Missing INTERFACE_NAME for corresponding IP_ADDRESS,
SUBNET_MASK,” >&2

   print ”         BROADCAST_ADDRESS or LANCONFIG_ARGS in the file”
>&2

   print ”         $NETCONF.  Excess variables will be ignored.”
>&2

   rval=$WARNING

fi

i=0

while ((i <= nIF)); do

   NAME=$(print ${INTERFACE_NAME[i]})

   INTERFACE_NAME[i]=$NAME          # without whitespace for route tests
below

   IP=$(print ${IP_ADDRESS[i]})

   IP_ADDRESS[i]=$IP                 # without whitespace for route tests
below

   if [[ $IP = “RARP” ]]; then

      IP=`/usr/sbin/rarpc $NAME`

      IP_ADDRESS[i]=$IP              # without whitespace for route tests
below

   fi

   if [[ -n $NAME && -n $IP ]]; then

      MASK=$(print ${SUBNET_MASK[i]})

      [[ -n “$MASK” ]] && MASK=”netmask $MASK”

      BCAST=$(print ${BROADCAST_ADDRESS[i]})

      [[ -n “$BCAST” ]] && BCAST=”broadcast $BCAST”

      PROTO=$(print ${LANCONFIG_ARGS[i]})    # do not set PROTO to any
default

      emsg=$(ifconfig $NAME $IP $MASK $BCAST up 2>&1)

      status=$?

      if ((status == 0)) && [[ -n $PROTO ]] ; then

         emsg=$(lanconfig $NAME $PROTO 2>&1)

         status=$?

      fi

      if ((status != 0)); then

         print “ERROR:   $NAME interface: $emsg” >&2

         rval=$ERROR

      fi

   fi

   let i=i+1

done

IP=$(print $LOOPBACK_ADDRESS)

if [[ -n $IP ]]; then

   emsg=$(ifconfig lo0 $IP up 2>&1)

   if (($? != 0)); then

      print “ERROR:   lo0 interface: $emsg” >&2

      rval=$ERROR

   fi

else

   print “ERROR:   Missing LOOPBACK_ADDRESS in the file $NETCONF.”
>&2

   print ”         lo0 interface not initialized.” >&2

   rval=$ERROR

fi

# Do route command for each configured route

# Note:  ${IP_ADDRESS[i]} must have whitespace removed already (above)

# We must have the __same__ number of ROUTE_GATEWAYs as
ROUTE_DESTINATIONs.

# But we can have __fewer__ ROUTE_COUNTs and ROUTE_MASKs (defaulted).

n=$(maxindex ROUTE_DESTINATION)

if (($(maxindex ROUTE_GATEWAY) != n)) || \

   (($(maxindex ROUTE_COUNT) > n))

then

   print \

      “WARNING: Missing ROUTE_DESTINATION for corresponding ROUTE_GATEWAY”
>&2

   print ”         or ROUTE_COUNT in the file $NETCONF.” >&2

   print ”         Excess variables will be ignored.” >&2

   rval=$WARNING

fi

i=0

while ((i <= n))

do

   DEST=$(print ${ROUTE_DESTINATION[i]})

   GWAY=$(print ${ROUTE_GATEWAY[i]})

   if [[ -n $DEST && -n $GWAY ]]; then

      COUNT=$(print ${ROUTE_COUNT[i]})

      if [[ -z $COUNT ]]; then

         # default COUNT:  if GWAY is one of the local interface IP

         # addresses, count is 0; otherwise, count is 1.

         COUNT=1

         k=0

         while ((k <= nIF)); do

            if [[ $GWAY = ${IP_ADDRESS[k]} && -n ${INTERFACE_NAME[k]}
]]; then

               COUNT=0

               break;

            fi

            let k=k+1

         done

      fi

      ARGS=${ROUTE_ARGS[i]}

      MASK=$(print ${ROUTE_MASK[i]})

      if [[ -z $MASK ]]; then

          # No subnet mask

          if [[ -z $ARGS ]]; then

             # No arguments

             emsg=$(route add $DEST $GWAY $COUNT 2>&1)

          else

             # With arguments

             emsg=$(route $ARGS add $DEST $GWAY $COUNT 2>&1)

          fi

      else

         # Subnet mask has been entered.

         if [[ -z $ARGS ]]; then

            # No arguments

            emsg=$(route add $DEST netmask $MASK $GWAY $COUNT
2>&1)

         else

            # With arguments

            emsg=$(route $ARGS add $DEST netmask $MASK $GWAY $COUNT
2>&1)

         fi

      fi

      # ignore “entry in use” errors.  these can arise because we

      # booted via NFS diskless, which added routes already

      if (($? != 0)) && [[ -n ${emsg##*entry in use*} ]]; then

         print “ERROR:   $emsg” >&2

         rval=$ERROR

      fi

   fi

   let i=i+1

done

# add loopback route for local interfaces to improve performance

k=0

while ((k <= nIF))

do

   if [[ -n ${IP_ADDRESS[k]} && -n ${INTERFACE_NAME[k]} ]]; then

      emsg=$(route add ${IP_ADDRESS[k]} $LOOPBACK_ADDRESS 0 2>&1)

      if (($? != 0)) && [[ -n ${emsg##*entry in use*} ]]; then

         print “ERROR:   $emsg” >&2

         rval=$ERROR

      fi

   fi

   let k=k+1

done

exit $rval

##################### The End  ###########################

 소개

u      Shell 종류

/usr/bin/sh      POSIX Shell

/usr/bin/ksh     Korn Shell

/usr/old/bin/sh  Bourne Shell

/usr/bin/csh     C Shell

/usr/bin/keysh   Key Shell

/usr/bin/rksh    Restricted Korn Shell

/usr/bin/rsh     Restricted Shell

u      Shell Startup 파일

Korn Shell     /etc/profile -> $HOME/.profile -> $HOME/.kshrc

Bourne Shell   /etc/profile -> $HOME/.profile

POSIX Shell    /etc/profile -> $HOME/.profile -> $HOME/.kshrc

C Shell        $HOME/.login -> $HOME/.cshrc

2.Shell Parameter

u      Parameter Substitution

l         Parameter Setting

# Parameter=Value

# 변수명=값  : Named Parameter

l         Parameter의 Unsetting

# unset parameter

  # unset 변수명

u        Command Substitution

# $(command)       # `command`

# XX=”12345″

# echo $XX

12345

# HOST=‘hostname‘

# echo $HOST     : # HOST=`hostname` 문장은 # HOST=$(hostname)과 같다

ssosvr3           : 즉, `command` 문장과 $(command)는 같은 뜻이다

# PS1=‘hostname‘’:$PWD# ‘

# PS1=$(hostname)’:$PWD# ‘; echo $PS1

ssosvr3:/#

# W1=”A”; W2=”B”; W3=”C”

# WORD=${W1}AA${W2}BB${W3}CC

# echo $WORD

AAABBBCCC

# unset WORD

– $10과 ${10}은 다르다. 왜냐하면 $10은 positional parameter $1값에

   0값이 붙여서 출력되며, ${10}은 positional parameter 10번째의 값을

   나타내기 때문이다.

u        Positional Parameter(위치변수)

shell-script  arg1  arg2  arg3  arg4

$0               $1    $2     $3    $4

Positional Parameter : $1,$2,$3,$4

$0          shell script명을 나타낸다

$1          첫번째 argument를 나타낸다. 즉, arg1

$2          두번째 argument를 나타낸다. 즉, arg2

$*          “arg1 arg2 arg3 arg4 …” 즉,모든 argument와 같다.

$@          “arg1” “arg2” “arg3” “arg4…” 즉,개개의 argument와 같다.

$#          모든 argument의 갯수

$?          마지막으로 수행된 명령어가 return한 값

$$          현재 shell script를 수행하고 있는 shell의 process id(pid)

$!          현재shell에서 수행한 마지막 background의 pid

$_          shell command의 마지막 argument를 가르키며,shell start시에는

            shell의 절대 PATH를 가르킨다.

# set aaa bbb ccc ddd eee fff 

– set명령어를 옵션없이 사용하면 positional parameter를 setting한다.

# echo $0      sh   현재shell를 나타낸다.

# echo $1      aaa

# echo $#      5    $# 은 argument의 개수를 나타낸다.

# echo $*      “aaa bbb ccc ddd eee fff”

# echo $@      “aaa” “bbb” “ccc” “ddd” “eee”

– “$*” 와 “$@” 의 차이점은 $*은 Positional parameter의 모든값을 하나의

  문자열(string)으로 취급하며 $@ 는 string을 개개의 문자열로 취급한다.

# echo $$    7637   : shell의 process id

${parameter}           parameter의 값. 이것은 {}뒤에 붙어있는 문자나

                       숫자,_ 와 같은문자와 함께 사용할 때 필요하다.

${#parameter}          parameter값의 문자수. ${#*}나 ${#@}은 positional

                       parameter의 개수를 나타낸다.

${#identifier[*]}             배열 identifier에서 element의 수를 출력한다.

${parameter:-word}     parameter가 set되고 NOT NULL이면 parameter값을 출력하고,

                       그렇지 않으면 word의 값을 출력한다.

${parameter:+word}     parameter가 set되고 NOT NULL이면 word의 값을 출력하고,

                       그렇지 않으면 아무것도 출력하지 않는다.

${parameter:=word}     parameter가 set되고 NOT NULL이면 parameter의 값을

                       출력하고, 그렇지 않으면 word의 값을 출력하고 parameter에

                       word의 값을 assign한다. Positional parameter는

                       이렇게 setting할 수 없다.

${parameter:?word}     parameter가 set되고 NOT NULL이면 parameter값을

                       출력하고, 그렇지 않으면 word를 출력하고 shell를

                       exit한다. word가 생략되면 화면에 표준출력된다.

# dir1=/home/tmp

# echo ${dir1:-/usr/bin}

/home/tmp

# unset X

# echo ${X:-“X is unset”}

X is unset   : X가 unset또는 null이면 word가 출력된다.

# echo ${dir1:+/usr/bin}

/usr/bin     : dir1이 null이면 아무것도 출력되지 않는다.

# echo ${dir1:=/usr/bin}

/home/tmp    : dir1이 unset되었거나 null이라면 /usr/bin이 출력된다.

# echo ${dir1:?/usr/bin}

/home/tmp

# echo ${#dir1}

10               : /users/tmp 의 총 문자갯수

${parameter#pattern}   pattern이 parameter값의 첫문자와 같으면 그문자를

${parameter##pattern}  포함한 부분은 delete된다. ##은 wild card(*)시 사용함.

   

${parameter%pattern}   pattern이 parameter값을 끝문자와 같으면 그문자를

${parameter%%pattern}  포함한 문자는 delete된다. %%은 wild card(*)시 사용함.

# XX=/a/b/c/d/a/b

# echo ${XX#*a}

/b/c/d/a/b

# echo ${XX##*a}

/b

# echo ${XX%a*}

/a/b/c/d/

# echo ${XX%%a*}

/

# AA=”12345123″

# echo ${AA#1}

2345123

# echo ${AA##*1}

23

# echo ${AA%3}

1234512

# echo ${AA%%3*}

12

# echo ${AA#5}

12345123

# echo ${AA##*5}

123

# echo ${AA##*3*}

# echo ${AA##6*}

12345123

u        Tilde(~) Substitution

만약 user mary의 home directory가 /users/mary라면

# echo $HOME

/users/mary

# echo ~           : ~ 는 user의 home directory를 나타낸다.

/users/mary

# echo $PWD

/users/mary/tmp

# ls ~+/x*         : ~ 다음의 + 는 현재directory 즉, $PWD의 값을 가르킨다.

/users/mary/tmp/x_file1

/users/mary/tmp/x_file2

# echo $OLDPWD

/users/mary/mail

# ls ~-/f*         : ~ 뒤의 – 는 이전 directory 즉, $OLDPWD의 값을 가르킨다.

/users/mary/mail/from.mike 

/users/mary/mail/from.nick

u        Shell Command Grouping

l         ( command )  : subshell grouping

                 shell은 마치 또다른 script를 call한것처럼 subshell

                 환경에서 command를 수행한다.

l         { command ;} : brace grouping

                    shell은 현재의 shell 환경에서 연속해서command를

수행하며 마지막에 반드시 ;(세미콜론)을 써야한다.

# vi test1.sh

#! /usr/bin/sh

# (command)의 Example

A=”aaa”

B=”bbb”

C=”ccc”

( A=”AAA”

B=”BBB”

C=”CCC”

echo “PID $$ :

      $A $B $C” )

echo “PID $$ :

       $A $B $C”

:wq

# sh test1.sh

PID 28999 : AAA BBB CCC

PID 28999 : aaa bbb ccc

# vi test2.sh

#! /usr/bin/sh

# {command;}의 Example

A=”aaa”

B=”bbb”

C=”ccc”

{ A=”AAA”

B=”BBB”

C=”CCC”

echo “PID $$ :

      $A $B $C” ;}

echo “PID $$ :

       $A $B $C”

:wq

# sh test2.sh

PID 28955 : AAA BBB CCC

PID 28955 : AAA BBB CCC

u        Shell Script의 수행

# sh shell_script

# ksh shell_script

# chmod 777 shell_script

# ./shell_scipt

u        Shell Script Comment

l         shell script에서 comment는 첫라인에 # symbol를 넣는다.

l         shell script에서 첫라인의 #! /usr/bin/sh의 의미는 이 shell은

    Posix shell로 수행한다는 의미이다.

u        Input and Output

stdin(0)         standard input으로서 default는 keyboard이며

                 file descriptor값은 0 이다.

stdout(1)        standard output으로서 default는 terminal display이다.

                 file descriptor값은 1 이다.

stderr(2)        standard error로서 default는 terminal displsy이다.

                 file descriptor값은 2 이다.

<word            표준입력(file descriptor 0)으로 word를 사용한다.

>word            표준출력(file descriptor 1)으로 word를 사용하며,

word라는 file이 생성된다.

>|word           >word와 같으며 noclobber옵션이 설정되있어도 무조건 overwrite한다.

>>word           word라는 file이 존재하면 file에 append한다.

없으면 word라는file을 생성한다.

<>word           word를 입력으로 받아서 다시 word라는 file로 출력한다.

<<word           shell prompt에서 word라는 글자를 만날때까지 command를 입력할 수

                 있으며 word라는 글자를 만나면 shell command가 수행된다.

<&숫자           file descriptor 숫자의 file에서 data를 입력받는다.

>&숫자           file descriptor숫자를 가진 file로 출력한다.

<&-              표준입력을 close하여 keyboard로부터 입력받지 못한다.

>&-              표준출력을 close하여 terminal로 출력하지 않는다.

# ftp -n -i << AAA

>open mars

>user root password

>cd /users

>mget *

>close

AAA

#

# vi datafile       : data file작성

aaa

bbb

ccc

:wq

# vi read.sh

exec 5< datafile  : datafile을 file descriptor 5번으로 open한다.

read -u5 X        : 첫라인을 read하여 X변수에 assign한다.

read -u5 Y         : 둘째라인을 read하여 Y변수에 할당.

read -u5 Z        : 셋째라인을 read하여 Z변수에 할당.

exec 5<&-         : file descriptor 5번 file을 close한다.

echo “$X $Y $Z”   : file descriptor은 3-9까지 쓸수있다.

:wq

# sh read.sh

aaa bbb ccc

u        조건 표현식

test 또는 [ … ]             Integer,string.file등에 모두사용(old syntax)

(( … ))              Integer에만 사용(new syntax)

[[ … ]]              string,file에만 사용(new syntax)

l         String 표현식  # man test 참조

   
—————————————————————————-

[ -b file ]            file이 존재하고 block special file이면 참

[ -c file ]            file이 존재하고 character special file이면 참

[ -d file ]            file이 존재하고 directory이면 참

[ -e file ]            file이 존재하면 참

[ -f file ]            file이 존재하고 ordinary file이면 참

[ -g file ]            file이 존재하고 setgid bit가 set되있으면 참

[ -h file ]            file이 존재하고 symbolic link되었으면 참

[ -k file ]            file이 존재하고 sticky bit가 set되었으면 참

[ -p file ]            file이 존재하고 fifo special file또는 pipe이면 참

[ -r file ]            file이 존재하고 readable하면 참

[ -s file ]            file이 존재하고 file size가 0보다 크면 참

[ -u file ]            file이 존재하고 setuid bit가 set되 있으면 참

[ -w file ]            file이 존재하고 writable하면 참

[ -x file ]            file이 존재하고 executable하면 참

[ -L file ]            file이 존재하고 symbolic link이면 참

[ -O file ]            file이 존재하고 user가 effective user id와 같으면 참

[ -G file ]            file이 존재하고 group이 effective group id와 같으면 참

[ -S file ]            file이 존재하고 socket이면 참

—————————————————————————–

[ -n string ]          string의 길이가 non zero면 참

[ -z string ]          string의 길이가 zero이면 참

[ string ]                    string이 not null string이면참

# if [ -f /etc/rc.config ] ; then

# if [ ! -d /usr/bin ] ; then

# if [ -z “$NODENAME” ] ; then

# if [ -x /usr/dt/bin/dtrc ] ; then

# if [[ -n “$NAME” ]] ; then

# if [[ -s /var/spool/lp/pstatus ]] ; then

# if [[ -r /var/run/mrouted.pid ]] ; then

# if [[ -z “$pid” ]] ; then

# if /usr/sbin/envd ; then

# if /sbin/local_is_root ; then

# if [ “$ARRAYMON_PID” ] ; then

# if [ “$START_OV500” ] ; then

[ file1 -nt file2 ]    file1이 존재하고 file2보다 newer이면 참

[ file1 -ot file2 ]    file1이 존재하고 file2보다 older이면 참

[ file1 -ef file2 ]    file1이 존재하고 file2와 equal file이면 참

# if [ /sbin/init.d/spa –nt /sbin/init.d/set_date ] ; then

# if [ /aaa –ot /bbb ] ; then

# if [ /ccc –ef /ddd ] ; then

[ string1 = string2 ]  string1과 string2가 같으면 true

[ string1 = pattern ]  string1과 pattern이 같으면 true

[ string1 != string2 ] string1과 string2가 같지않으면 true

[ string1 != pattern ] string1과 pattern이 같지않으면 true

[ string1 < string2 ]  string1이 string2보다 작으면 true

[ string1 > string2 ]  string1이 string2보다 크면 true

# if [ “$pid” = “” ] ; then

# if [ X$pid != “X” ] ; then

# if [ $HOST != `hostname` ] ; then

# if [ “$MWASTART” > “1” ] ; then

# if [[ $? = 255 ]] ; then

[ exp1 -eq exp2 ]             exp1과 exp2가 같으면 참(equal)

[ exp1 -ne exp2 ]             exp1과 exp2가 같지 않으면 참(not equal)

[ exp1 -lt exp2 ]             exp1이 exp2보다 작으면 참(less than)

[ exp1 -gt exp2 ]             exp1이 exp2보다 크면 참(greater than)

[ exp1 -le exp2 ]             exp1이 exp2보다 작거나 같으면 참(less than or equal)

[ exp1 -ge exp2 ]             exp1이 exp2보다 크거나 같으면 참(greater than or
equal)

# if [ $x –ne 0 ] ; then

# if [ $? –eq 0 ] ; then

# if [ “$RWHOD” –eq 1 ] ; then

# if [[ “$rval” –eq ${EXIT_NA} ]] ; then

# while [ ${CNT} –le ${MAX_NISCHECKS} ] ; then

# if [ $# -ge 0 ] ; then

# if [ “$XX” –gt “$YY” ] ; then

# if [ “$X” –lt 1 ] ; then

# if [ $# -ne 1 ] ; then

# if [ `grep $HOSNAME /etc/mail/sendmail.cw|wc –l` -eq 0 ] ; then

( expression )         expression이 참이면 참

! expression           Binary NOT 연산자

exp –a exp2            Binary AND 연산자, 우선순위가 –o 보다 높음.

exp –o exp2            Binary OR 연산자

exp1 && exp2           exp1과 exp2가 모두 참이면 참

exp1 || exp2           exp1가 참이거나 exp2가 참이면 참

# if [ “$GATED” –eq 0 –a “X$pid” = “X” ] ; then

# if [ “$CRON” –eq 1 –a –x /usr/sbin/cron ] ; then

# if [ “$NIS_DOMAIN” –a –f /usr/bin/domainname ] ; then

# if [ “$NIS_MASTER” –ne 0 –o “$NIS_SLAVE” –ne 0 ] ; then

# if [ “$9” = ‘S’ ] || [ “$9” –lt ‘2’ ] ; then

# if [ “$VTDAEMON_START” –eq 1 ] && [ -x /usr/sbin/vtdaemon ] ;
then

# if [[ -r /usr/sbin/swagentd# ]] && [[ -h /usr/sbin/swagentd ]] ;
then

# if [ $status !=2 –o –z “$DOMAIN” –o –z “$SERVER” ] ; then

# if (( status == 0 )) && [[ -n $PROTO ]] ; then

l         Integer 표현식

(( integer1 == integer2 ))    integer1과 integer2가 같으면 참

(( integer1 != integer2 ))    integer1과 integer2가 같지 않으면 참

(( integer1 < integer2 ))           integer1이 integer2보다 작으면 참

(( integer1 > integer2 ))           integer1이 integer2보다 크면 참

(( integer1 <= integer2 ))    integer1이 integer2보다 작거나 같으면 참

(( integer1 >= integer2 ))    integer1이 integer2보다 크거나 같으면 참

# if (( $? != 0 )) ; then

# while ((n>0))

# if ((n<2) || !length(part[2])) ; then

# if ( $1 != mypid ) ; then

# if (( $1 > $2 )) ; then

3.Shell Programming

u        if 조건문

if 조건문

then

   명령어

[elif 조건문

then

   명령어]

[else

   명령어]

fi

if 조건문; then 명령어; [elif 조건문; then 명령어;] [else 명령어;] fi

:wq# vi if1.sh

X=hello

if [ $X = hello ]

then

   echo “Welcome”

else

   echo “Goodbye”

fi

:wq

# sh if1.sh

Welcome

# vi if2.sh

if [ -f temp ]

then

   mv temp temp1

elif [ -f temp1 ]

then

   mv temp1 temp2

fi

:wq

# sh if2.sh

u        case 조건문

case 변수 in

변수값1|변수값2…)

   명령어;;

변수값3|변수값4…)

   명령어;;

*)

   명령어;;

esac

#  vi case.sh

case $1 in

-d|-r)

        rmdir $dir1

        echo “directory removed” ;;

-o)

        echo “option -o” ;;

*)     

        echo “Invalid option,Try again…” ;;

esac

:wq

# chmod 777 case1.sh

# ./case.sh -o

option -o

u        while 반복문

while 조건문

do

   명령어

done

– 다음은 모두 같은 while문이다.

while [ 1 ]

do

  echo “Test”

done

while true

do

  echo “Test”

done

while [ : ]

do

  echo “Test”

done

while :

do

  echo “Test”

done

# vi while1.sh

count=$(who|grep -v root|wc -l)

while [ “$count” -gt 0 ]

do

   echo “Users still logged in…”

   sleep 1

   count=$(who|grep -v root|wc -l)

done

:wq

# sh while1.sh

# vi while2.sh

# /usr/bin/sh

#

print -n “Enter a value : “

read Value

print “Thank You”

count=0

while [ “$count” -lt “$Value” ]

do

   (( count=count + 1 ))

   print “Still sleeping for the $count th time…”

   sleep 2

done

print “End of $0”

:wq

# sh while2.sh

u        for 반복문

for 변수 [in 변수값1,변수값2,…]

do

   명령어

done

# vi for1.sh

for name in $(cut -d -f1 /etc/passwd)

do

   mailx $name < message.txt

   echo “Mail sent to $name”

done

:wq

# sh for1.sh

# vi for2.sh

if [[ ! -d “$1” ]]

then

   exit 1

fi

filename=$(ls $1)

for onefile in $filename

do

   if [[ -f ${1}/$onefile ]]

   then

      ll ${1}/$onefile

   elif [[ -d ${1}/$onefile ]]

   then

      ll -d ${1}/$onefile

   fi

done

:wq

# sh for2.sh /etc

u        until 반복문

until 조건문

do

   명령어

done

# vi until.sh

count=$(who|grep -v root|wc -l)

until [ “$count” -eq 0 ]

do

   echo “Users still logged in…”

   sleep 1

   count=$(who|grep -v root|wc -l)

done

:wq

# sh until.sh

u        select 반복문

select 변수 [in 변수값1,변수값2,…]

do

   명령어

done

– select문은 PS3 prompt를 사용한다. PS3 shell 변수의 기본값은 #? 이다.

– 변수는 변수값1,변수값2,… 등이 할당된다.

– 입력된 변수의 값의 숫자는 REPLY라는 shell변수에 저장된다.

– exit,return,break 등의 명령어로 반복문을 빠져나올수 있다.

– [in 변수값1,변수값2,…]가 없을경우에는 Positional Parameter를 사용한다.

# vi edit.sh         ### Edit the file ###

select menu in $(ls) “Exit” ; do

   case $menu in

     Exit) exit;;

     “”) echo “Invalid selection. Try again!”;;

     *) cp $menu $menu.bak; vi $menu ;;

   esac ; done

:wq

# vi color.sh

  select color in red blue green

  do

     echo “$color is an $color color”

     echo “$REPLY is a REPLY value”

  done

:wq

# sh color.sh

1)red

2)blue

3)green

#? 1

red is an red color

1 is a PEPLY value

#? 2

blue is an blue color

2 is a REPLY value

#? ^C

#

# vi select.sh

PS3=”Enter your choice =>”

select menu in “full backup”

                  “partial backup”

do

 case $menu in

 “full backup”)

  fbackup –0uf /dev/rmt/0m –i /stand

  echo “Full backup has begun”

  exit 0;;

 “Partial backup”)

fbackup –0uf /dev/rmt/0m -i /opt

echo “Partial Backup has begun”

return;;

 *) echo “$REPLY is an invalid

             option. Try again!”;;

 esac

done

:wq

# sh select.sh

# vi nest.sh

  #### Nested Select Command Example ###

#! /usr/bin/sh

PS3=”Main Choice by number=>”

select menu in “List Files” “Exit”

do

   case $menu in

   “List Files”)

      PS3=”Sub Choice by number=>”

      select ls_option in “Short” “Long” “Main”

      do

         case $ls_option in

          “Short”) lsf;;

           “Long”) ll;;

           “Main”)

               PS3=”Main Choice by number=>”  ## Restore Prompt

               break 1 ;;  ## exit inner loop

           “”) echo “$REPLY is an invalid option. Try again!”;;

         esac

      done ;;

   “Exit”) exit;;

   “”) echo “$REPLY is an invalid option. Try again!”;;

   esac

done

:wq

# sh nest.sh

u        Function(함수)

function 함수명

{

  shell script

}

함수명()

{

  shell script

}

– shell script안에 선언할수도 있고 밖에 선언할수도 있다.

– 함수명이나 argument로 called될수 있다.

– 같은 process를 반복적으로 사용할때 유리하며 debugging하기가 쉽다.

– typeset -xf name 으로 함수명을 export하여 global 함수로 선언할수 있다.

# vi func1.sh

function exef

{

   if [ -x $1 ]

   then

      echo “$1 is executable”

   fi

}

for file in `ls`

do

   exef $file

done

:wq

# sh func1.sh

# vi func2.sh

Uppercase()

{

   echo $* | tr “[a-z]””[A-Z”]”

}

print -n “Enter in a string:”

read string

upper_string=$(Uppercase $string)

echo “The uppercase string is: $upper_string”

:wq

# sh func2.sh

# vi func3.sh       : Recursive Fuction

bottom_up

{

   typeset SAVEPWD

   echo “\nDirectory being listed is: $PWD\n”

   lsf

   if [ “$PWD” != “/” ]

   then

      SAVEPWD=$PWD

      cd ..

      bottom_up

      cd $SAVEPWD

   else

      echo “That’s the end!”

   fi

}

:wq

# sh func3.sh

u        Array(배열)

– shell script에서 사용할수 있는 배열은 1차원배열이다.

– 배열요소(element)는 최대 512-1024까지 쓸수 있다.

– 배열요소는 [0]부터 [1023]까지 쓸수 있다.

– Array subscript인 [N]에서 N은 integer또는 integer expression을 쓸수 있다.

# X[0]=first

# X[1]=second

# X[2]=third

# echo ${X[1]}

second

# echo ${X}         : ${X}는 ${X[0]}과 같음

first

# echo ${X[*]}             : ‘*’나 ‘@’는 모든 요소를 가르킴

first second third

# echo ${#X[*]}

3

# i=3

# X[2*(i+1)]=10

# print ${X[8]

10

# set -A YY 100 200 300    : set -A는 변수를 배열로 선언한다.

# print ${YY[0]} ${YY[1]} ${YY[2]}

100 200 300

# set +A YY 150

# print ${YY[@]}

150 200 300

4.Shell Command

u        : 명령어

– ‘:’ 명령어는 아무것도 수행하지 않으며, 어떤 영향도 미치지 않는다. ‘0’값이 return됨.

# vi xx.sh

if [ -f /opt ]; then

   ls

else

   :            아무것도 수행하지 않는다.

fi

:wq

u        . 명령어

# . /etc/profile

– /etc/profile이라는 프로그램을 수행한다. 이는 sh나 ksh처럼 또하나의 shell을 fork하여

  프로그램을 수행하지 않으며 이 프로그램은 수행가능한 permission이 없어도 된다.

  즉 이 파일은 ‘x’ permission이 없어도 된다.

u        alias 명령어

alias [-x] [ name[=value] … ]

# alias                             : 현재 setting된 모든 alias를 display

# alias a=alias

# a x=lsf

# alias i=’

> echo Users logged in are:

> who|sort

> echo I am `whoami`’

# i                                  : alias문을 수행한다.

# unalias i                        : alias변수 i를 unsetting한다.

# unalias -a                       : shell command에서 typing한 모든

                                        alias를 해제한다.

# alias -x who=’who|sort’       : Korn shell에서 who를 export하여

                                        subshell에서도 사용가능하다.

u        break 명령어

break [n]

– for,while,until,select문과 같은 반복문에서 exit할 때 사용한다.

– n을 쓰면 n레벨만큼 loop를 exit한다.

# vi break.sh

for file in x y z none

do

   if [ -x $file ]; then

      echo $file

      break

   fi

done

:wq

u        command 명령어

command [arg …]

– argument를 command로서 취급한다.

# command lsf       : lsf를 command로 사용한다.

# command aaa       : aaa를 command로 사용한다.

u        continue 명령어

continue [n]

– for,while,until,select문과 같은 반복문에서 continue이하의 문을 수행하지 않고

다시 시작한다.

    – n을 쓰면 n번째 반복문을 다시 시작한다.

# vi con.sh

for file in x y z

do

   if [ -x $file ]; then

      continue

      echo “$file is executable”

   fi

   echo $file is not executable

done

:wq

u        echo 명령어

echo [arg …]

# echo ‘This is a’ $var ‘example.’

# echo “This is a $var example.”

# echo “Enter your user name: \c”

> read user

> echo ‘User is’ $user

echo 에서 Escape Character

\b     backspace

\c     continue line. new line을

       하지 않고 계속 붙여서 print한다

\f     form feed

\n     new line

\r     carriage return

\t     tab

\v     vertival tab

\\     backslash

u        eval 명령어

eval [arg …]

– argument를 input으로 받아서 명령어로 수행하며 argument는 command나 shell

  script가 될수 있다.

# cmd=’ps -ef > ps.out’

# eval $cmd

# eval “grep jones $file|set|echo $1 $2 $3”

u        exec 명령어

exec [arg …]

– 새로운 process나 subshell을 만들어서 argument를 수행하지 않고 현재 shell로

  명령어를 바로 수행한다.

# exec 3< file          file desciptor number 3으로 file을 open한다.

# ecec 2> /dev/null     표준에러를 /dev/null로 출력한다.

u        expr 명령어         # man expr 참조

expr expression {+,-,\*,/} expression

expr expression {=,\>,\>=,\<,\<=,!=} expression

expr string1 : string2

# a=15

# expr $a + 5

20

# count=`expr $count + 5`

# A=batman

# expr substr $A 1 3

bat

# expr index $A m

4

u        fc 명령어

fc [-r] [-e example] [first [last]]

fc –l [-nr] [first [last]]

fc –s [old=new] [first]

fc –e – [old=new] [command]

– fc command는 history file을 list하거나 history file에서 command를 edit할 수있다.

# fc –l            : history file의 내용을 display한다.

# fc –l 20 25

# fc –l 10

# fc –e vi 15 20

# fc –e –          : 방금 실행한 command를 다시 실행한다. # r 명령과 같다.

# fc –e – ls=cd  

u        let 명령어

let “expression”

(( expression ))

– let는 산술 표현을 가능하게 하며 long integer 계산을 한다.

Operator

Description

!

/  %

+  –

<  <=  >  >=

==  !=

=

unary minus

logical negation

곱하기,나누기,몫

더하기,빼기

비교

같다,같지 않다

변수 할당

# x=10

# y=2

# let x=x+2

# echo $x

12

# let “x=x/(y+1)”

# echo $x

4

# (( x=x+1 ))

# echo $x

5

# x=12

# let “x<10”

# echo $?

1

# (( x > 10 ))

# echo $?

0

# if (( x > 10 ))

>then echo x greater

>else echo x not greater

>fi

x greater

u        read 명령어

read [-r] name…        : POSIX Shell only

read [-prsu] [name]    : Korn Shell only

-r          라인연속으로 쓰인 라인끝의 \를 해석하지 않는다.

-un         file descriptor n 으로부터 input을 read한다.

# vi read.sh

  while read -r xx yy

  do

     printf “%s %s \n” “$yy” “$xx”

done < input_file

:wq

u        return 명령어

return [n]

– 함수의 실행을 마치고 calling shell script에게 exit status n을 return한다.

– n이 없으면 return status는 함수의 마지막 command의 값이다.

– return이 함수의 밖에서 수행되면 exit로서 실행된다.

# vi return.sh

  search()

  {

     if grep xxx “$1” > /dev/null 2>&1

     then return 1

     else return 2

     fi

  }

:wq

# sh return.sh filename

u      set 명령어

l         Positional Parameter값 setting

# set spring summer fall winter

# echo $3

fall

# echo $*

spring summer fall winter

l         Positional Parameter Sorting

# set third first second

# echo $1 $2 $3

third first second

# set –s               : 값을 lexical order로 sorting함

# echo $1 $2 $3

first second third

# set +s            : unsetting

option         option-name meaning

——————————————————————————–

set –a         allexport   모든 parameter가 자동으로 export됨. == set -o
allexport

set -C         noclobber   #date>XX시 >로 overwrite하지못하게 함. date>|XX로는
가능

set –e         errexit     shell command fail시 즉시 logout또는 shell을 exit함

set –f         noglob             # ls * 시wild card문자를 인식못함

set –h         trackall   

set –k         keyword    

set –m         monitor     Background jogs이 각각다른 process group에서 수행되고

                           작업이 끝나면 message를 report함

set –o                     set –o monitor와 같이 option-name에 붙여서 옵션을

                           setting함

set –s                     positional parameter를 sort함

set –t                     shell을 exit한후에 command를 수행함

set –u         nounset     substituting시 unset parameter를 error로 취급함

set –v         verbose     command를 display한후 command 수행

set –x         xtrace             command수행시 command와 argument까지 print함.

                           shell script의 debug mode로 사용함.

              

set                        현재 setting된 모든 shell variable을 list함

set –                      -x와 –v option을 turn off하고 flag에 대한 argument

                           검사를 하지 않음

set —                     옵션의 어떤 변화도 하지못하게 함. # set — -;echo $1

                                      file명으로 시작하는 file을 rm할 경우 # set — -;rm
–aaa

# set –o ignoreeof          : ignoreeof라는 옵션을 turn on

# set +o vi                : vi의 옵션을 turn off

# set –o noglob            : noglob옵션을 turn on 시키고 wild card인

                                    *,[],-,!,? 등을 shell이 해석하지 못하게함

# set –o noexec            : shell의 syntax error를 check하기위해 사용.

                             이 옵션은 interactive shell에서는 사용되지

                                    않으며 shell script에서만 수행됨.

                             noexec 옵션은 실제로 shell을 수행하지 않으면서

                                       shell의 syntax error만을 check하는
명령어다.

# vi set1.sh

  set –o noexec

  echo “This is test

  ls

  cp /aaa /bbb

:wq

# ksh set1.sh

set1.sh: syntax error at line 2 : ‘”‘ unmatched

# vi set2.sh

  set –x

  ls

  echo “The Test”

  set +x

  lsf

:wq

# sh set2.sh

u        shift 명령어

shift [n]

shift command는 positional parameter($1,$2,$3..)의 내용을 왼쪽순으로 move한다.

# vi shift1.sh

  yflag=0

  zopt=””

  for arg in “$@”

  do

     if [ “x$arg” = x-y ]

     then

        yflag=1

        shift

     else

       zopt=”$2″

       shift 2

     fi

  done

:wq

u        trap 명령어

trap [command] [signal]

– signal 값은 # kill –l또는 # man kill 명령어로 볼수 있음.

# trap “echo ‘Command Failed'” 2

                       : ^C(interupt)를 치면 echo 문장이 수행됨.

# trap              : trap 명령을 수행한후 옵션이 없이 trap명령을 수행하면 현재

                    setting된 모든 trap내용을 보여줌

# trap “” 1 2 3

                       : 1}HUP 2)INT 3)QUIT가 입력되도 무시하라.

# trap “echo logout” 0

                       : signal이 ‘0’ 이면 NULL signal로서

                         shell에서 exit할때 command가 수행된다.

u      typeset 명령어

typeset [-][+]옵션  변수명[=변수값]

option      meaning

—————————————————————————–

[-]         변수명의 속성을 setting

[+]         변수명의 속성을 turn off

-Ln         왼쪽의 공백을 제거하고 왼쪽에서 n숫자만큼 cut

-Rn         왼쪽에 공백을 채우고 오른쪽에서 n숫자만큼 cut

-Z          오른쪽으로 shift하고, 첫번째 문자가 숫자이고 –L옵션과 같이

            쓰지 않았으면 왼쪽에 숫자0을 채움

-i          변수명을 integer로 선언

-f          변수명이 아니라 함수명으로 변수를 선언

-l          모든 영문대문자를 소문자로 변환

-u          모든 소문자를 대문자로 변환

-r          변수를 read-only로 만듬,즉 변수를 상수로 만듬

-x          변수를 export함, 즉 변수를 전역변수로 만듬

—————————————————————————–

# typeset

현재 setting되어있는 변수의 data type을 보여줌

# typeset AA

AA변수를 string변수로 선언,또한 함수내에서 Local변수 즉 지역변수로 선언

하지만, shell에서 변수는 default로 string data type임

# DATA=”Today we had very HOT weather”

# typeset –u DATA

# echo $DATA

TODAY WE HAD VERY HOT WEATHER

# typeset +u DATA : DATA변수의 속성을 turn off 

# DATA=”as of the “${DATA}

# echo $DATA

as of the TODAY WE HAD VERY HOT WEATHER

# AAA=123456789

# typeset –L3 AAA

# echo $AAA

123

# typeset –LZ X=00005

# print $X

5

# typeset –i X        : 변수X를  integer로 선언 # integer X와 같음

# typeset –i2 X     : 변수X를 2진수로 선언

# typeset –i8 X     : 변수X를 8진수로 선언

# typeset –i10 X    : 변수X를 10진수로 선언

# typeset –i16 X    : 변수X를 16진수로 선언

# typeset -r Y=123  : 변수Y를 readonly변수로 선언 # readonly Y=123과 같음

# typeset -f        : 모든함수와 그 값을 display함

# typeset -xf       : export된 모든함수와 그 값을 display함

# typeset -xf XX    : 함수명 XX를 export하여 global function으로 선언함

u        ulimit 명령어

ulimit  [-f] [n]

– ulimit command는 child process나 subprocess에 의해 사용된는 resources를 제한한다.

# ulimit               : 현재 limit값을 보여준다

# ulimit –f 1000       : 현재process나 향후 process가 write할 수 있는

                          file size를 1000 block(1000*512 byte)으로 제한한다.

# ulimit –f unlimited : child process가 생성할 수 있는 size의 제한을 없앤다.

5.Regular Expression(정규 수식)

u        Pattern Matching과 Regular Expression의 비교 – # man 5 regexp참조

Pattern Matching

Regular Expression

– POSIX shell에서 사용

– file name생성과 case문에서 사용

– UNIX command와 Text Editor에서 사용

  (ed,vi,ex,sed,awk,expr,grep)

– file name을 match한다

– character string을 match한다

– file name을 substitute한다

– string을 search해서 substitute한다

– 사용되는 특수문자

  ?,  *,  [ – ],  !

– 사용되는 특수문자

  .,  [],  -,  ^,  $,  *

u        하나의 문자와 Match – .(dot)

A.          : AB,Ab,AA,A9등과 같이 A다음에오는 어느한문자와 match

…         : 연속된 3문자와 match

# man 5 regexp|col -b|expand > regexp.man

# grep ‘RE.’ regexp.man       : RE다음에오는 어느한문자와 Match되는 라인만 출력

u        문자의 시작과 Match – ^

^abc        : 첫문자가 abc로 시작되는 문자와 match. abc,abcabc,abcdef등과 match

^C          : 문자의 시작에서 C와 match

^C$         : 하나의 문자 C와 match

^.$         : 하나의 문자로만 구성된 문자와 match

^[ABC]      : 첫문자가 ABC로 시작되는 문자와 match

u        문자의 끝과 Match – $

abc$        : 끝문자가 abc로 끝나는 문자와 match. defgabc,cccabc,abc등과 match

^…$       : 3개의 문자로만 구성된 문자와 match

\.$         : 문자의 끝에서 마침표(.)과 match

\*$         : 문자의 끝에서 (*)와 match

u        문자 Match – []

[Tt]he      : The나 the라는 글자를 search

h[iau]t     : hit,hat,hut의 글자와 match

[ABC]       : A,B,C를 포함하는 문자와 match

u        범위를 포함하는 문자와 Match – [ – ]

[a-z]       : 소문자 a부터 z까지 어느문자와도 match

[0-9]        : 0-9까지 어떤 하나의 숫자와 match

[0-57]      : 0,1,2,3,4,5,7과 match

[a-c5-8X-Z] : a,b,c,5,6,7,8,X,Y,Z중 하나의 문자와 match

[0-3-]      : 0,1,2,3,-와 match

u        Complemented문자 Match – [^  ]

[^ ]        : 공백이 아닌 한문자와 match

[^0-9]      : 0-9까지 숫자가 아닌 하나의 모든문자와 match

[^a-zA-Z]   : 영문 알파벳이 아닌 문자나 숫자와 match

[012^]      : 0,1,2,^와 match

^[^a-z]$    : 소문자을 제외한 나머지 문자중 하나와 match

# man 5 regexp|col -b|expand > regexp.man

# grep ‘^$’ regexp.man|wc -l         : 공백라인수를 출력한다.

# TMOUNT=`/sbin/mount | grep ‘^/tmp(/| )’ | wc -l`

# grep -q -e “^/usr/bin$” -e “^/usr/bin:” -e “:/usr/bin:”\

         -e “:/usr/bin$” /etc/PATH

u        Null 또는 여러 같은문자와 Match – *,+,?

B*          : Null문자,B,BB,BBB…등과 match

AB*C        : AC,ABC,ABBC…등과 match

A+          : A,AA,AAA…등과 match

AB+C        : ABC,ABBC,ABBBC…등과 match

A?          : Null문자 또는 A와 match

AB?C        : AC,ABC와 match

[A-Z]+      : 하나이상의 대문자와 match

(AB)        : AB문자와 match

(AB)+C      : ABC,ABABC,ABABABC…등과 match

AB.*XYZ     : ABXYZ,ABCXYZ,ABCCCCXYZ…등과 match

u        특수문자 Match – \

\*          : 특수문자 *와 match

\$          : 특수문자 $와 match

\\          : 특수문자 \와 match

\\\\\.\*$   : 문자의 끝에서 \\.* 와 match

u        Subexpression – \( … \)

– \(…\)구문을 사용한다.

– subexpression과 match하는 문자를 recall하기위해 ‘\숫자’를 사용한다.

– ‘\숫자’ 는 1-9까지 쓸수있다.

– \1 은 1번째 subexpression,\2 는 2번째 subexpression을 나타낸다.

# who

root       console      Oct 23 13:01

root       ttyp1        Oct 27 12:45

root       pts/0        Oct 22 09:03

# who|sed ‘s/\([^ ][^ ]*\)[^A-Z][^A-Z]*\(.*\)/\2–>\1/’

Oct 23 13:01–>root

Oct 27 12:45–>root

Oct 22 09:03–>root

– 첫번째 /\([^ ][^ ]*\) 는 공백이 아닌 하나이상의 문자와 match하며 뒷부분의

  \1 의 값과 같다.즉, 여기서는 username root를 가르킨다.

– 두번째 \(.*\) 는 최초로 대문자로 시작되는 문자와 match하며 뒷부분의

  \2 의 값과 같다. 여기서는 Oct를 가르킨다.

6.Sed(Stream Editor)

u        sed 형식

sed [-n] command input_file…

sed [-n] [-e command]… [-f script_file]… [input_file…]

-n          화면에 display하지 않는다. 단  p명령어일경우는 화면에 display한다.

            -n옵션은 -e나 -f옵션중 하나와 같이 사용할수 있다.

-e command  command를 editing하며, input file이 없으면 표준입력이 사용된다.

-f script   input file에서 editing command의 script file을 수행한다.

– sed는 입력파일로부터 한라인씩 data를 read한다.

– sed는 default로 화면에 출력을 하며 input file을 modify하지 않는다.

# sed “s/UNIX/Unix/g” file1 > file2.new

# sed -e “s/Miss/Ms/g” -e “s/Mrs/Ms/g” file2

# sed -n “1,10p” file2

# cat script

1,10p

# sed -n -f script file2

u        s(substitute)

[address [,address]] s/string_old/string_new/[flag]

flag        meaning

g           global substitution(전라인을 모두바꾼다)

p           print line

w file      file로 write한다

# sed “s/[Cc]omputer/COMPUTER/g” file1

# sed -e “1,5s/abc/xyz/” -e ‘s/kbs/mbc/’ file1 > file2

# sed “/abcde/s/ab/AB/g” file1

# sed -e ‘s/abc/xyz/w file2’ file1

# sed “3s/the/xyz/g” file1

# sed ‘3s/^the /xyz/’ file1

# sed -e “/the/s/ for /xyz/g

# cat file1| sed “/the/s/ for /xyz/gw file2

# sed “1,8s/aaa/bbb/g” file1 > file2

# sed “/^5/,/^15/s/from/FROM/g”

# sed -e “/^The first time/,/^End of file/s/lsf/ll/g”

# sed “1,$s/\/usr\/bin/\/sbin\/bin/g”

u        d(delete)

# sed “1,10d” fileA

   – fileA에서 1-10라인까지 delete한다.

# sed “/^From/!d” mbox

   – mbox file에서 From으로 시작되는 라인만 제외하고 모두 delete한다.

u        p(print),l(list),=,q(quit),r(read),w(write)

p           standard output에 print한다. -n옵션과 함께써도 print된다.

l           nonprinting문자도 같이 표준출력한다.

=           address 라인의 라인번호를 표준출력한다.

q           현재라인을 출력하고 sed를 종료한다.

r file      file의 내용을 read하여 표준출력한다.

w file      file에 address라인을 write또는 append한다.

# vi cap

   One potato, teo potato,

   three potato, four.

   Five potato, six potato,

   seven potato, more.

:wq

# sed -n “1,2p” cap

One potato, two potato,

three potato, four.

# sed -e “q” cap

One potato, teo potato,

# sed -e “/\./=” -e ” /[A-Z]/w file1″ cap

One potato, teo potato,

2

three potato, four.

Five potato, six potato,

4

seven potato, more.

# killproc() {

      for x in “$@”

      do

         pid=`ps -e |grep “$x” |sed -e ‘s/^  *//’ -e ‘s/ .*//’`

         [ ! –z “$pid” ] && echo killing $x && kill $pid
&

      done

  }

# findproc() {

    pid=`ps –e |grep “$1” |sed -e ‘s/^  *//’ -e ‘s/ .*//’`

    echo $pid

  }

# killproc() {           

      echo stopping $1

      pid=`/usr/bin/ps -e |

            /usr/bin/grep “$1” |

            /usr/bin/sed -e ‘s/^  *//’ -e ‘s/ .*//’`

            [ “$pid” != “” ] && kill $pid

  }

# if [ “$RWHOD” –ne 1 ]; then

      rval=2

  else

      pid=`ps -el | awk ‘( ($NF ~ /rwhod/) && ($4 != mypid)
&&

           ($5 != mypid)) { print $4 }’ mypid=$$ `

      if [ “X$pid” != “X” ]; then

         if kill $pid; then

            echo “rwhod stopped”

         else

            rval=1

            echo “Unable to stop rwhod”

         fi

      fi

  fi

#

#

#

# ARRAYMON_PID=`ps -ef | awk ‘$0 ~ /.*arraymon*/ && $0 !~
/.*awk.*/

                  { print $2 }’`

  if [ “$ARRAYMON_PID” ]

  then

     echo “Killing disk array monitor daemon.”

     kill -9 $ARRAYMON_PID

     sleep 2

     ARRAYMON_PID=`ps -ef | awk ‘$0 ~ /.*arraymon*/ && $0 !~
/.*awk.*/

                     { print $2 }’`

     if [ “$ARRAYMON_PID” ]

     then

       echo “ERROR:  Could not kill ${ARRAY_MONITOR_DAEMON}”

     fi

  fi

#

7.Shell Program 예제

-shell script를 위한 data file은 다음과 같다.

# vi data

  100 200 300 400

  500 600 700 800

  900 1000 1100 1200

  1300 1400 1500 1600

  1200 800 400 0

:wq

# vi exp1.sh

if [[ ! -f “$1” ]]

then

   echo “${0##*/}”

   exit 1

else

   filename=$1

fi

exec 3< $filename : file descriptor 3으로 filename를 open

typeset -i II=0   : XX를 integer로 선언

while read -u3 AA[0] AA[[1] AA[2] AA[3]

do

   for II in 0 1 2 3

   do

      (( total[II]=${total[II]} + ${AA[II]} ))

   done

print “Subtotal : “

print ${total[*]}

done

print “Total for the four columns are : “

print ${total[@]}

:wq

# sh exp1.sh

#!/usr/bin/sh

######################## /etc/profile ##########################  

trap “” 1 2 3                   

PATH=/usr/bin:/usr/ccs/bin:/usr/contrib/bin

MANPATH=/usr/share/man:/usr/contrib/man:/usr/local/man

if [ ! -d /usr/sbin ]

then

   PATH=$PATH:/sbin

else

   if [ -r /etc/PATH ]

   then

      grep -q -e “^/usr/bin$” -e “^/usr/bin:” -e “:/usr/bin:”\

                -e “:/usr/bin$” /etc/PATH

      if [ $? -eq 0 ]

      then

         PATH=`cat /etc/PATH`

      else

         PATH=$PATH:`cat /etc/PATH`

      fi

   fi

fi

export PATH

if [ -r /etc/MANPATH ]

then

   MANPATH=`cat /etc/MANPATH`

fi

export MANPATH

if [ -r /etc/TIMEZONE ]

then

   . /etc/TIMEZONE 

else

   TZ=MST7MDT       

   export TZ

fi

if [ ! “$VUE” ]; then

   if [ “$TERM” = “” -o “$TERM” = “unknown” -o “$TERM” = “dialup”  \

                         -o “$TERM” = “network” ]

   then

      eval `ttytype -s -a`

   fi

   export TERM

   if [ “$ERASE” = “” ]

   then

      ERASE=”^H”

      export ERASE

   fi

   stty erase $ERASE

   trap “echo logout” 0

   cat /etc/copyright

   if [ -r /etc/motd ]

   then

      cat /etc/motd

   fi

   if [ -f /usr/bin/mail ]

   then

      if mail –e

      then echo “You have mail.”

      fi

   fi

   if [ -f /usr/bin/news ]

   then news –n

   fi

   if [ -r /tmp/changetape ]

   then

      echo “\007\nYou are the first to log in since backup:”

      echo “Please change the backup tape.\n”

      rm -f /tmp/changetape

   fi

fi

trap 1 2 3

###################### The End ##########################

#!/usr/bin/sh

############# /.profile ################  

set +u

PATH=/usr/sbin:$PATH:/sbin:/home/root

if [ ! “$VUE” ]; then

   if [ “$TERM” = “” ]

   then

      eval ` tset -s -Q -m ‘:?hp’ `

   else

      eval ` tset -s -Q `

   fi

   stty erase “^H” kill “^U” intr “^C” eof “^D” susp “^Z”

   stty hupcl ixon ixoff

   tabs

   echo

   echo “Value of TERM has been set to \”$TERM\”. “

   export TERM

   EDITOR=vi

   export EDITOR

fi

set –u

trap “echo ‘logout root'” 0

MAIL=/var/mail/root

echo “WARNING:  YOU ARE SUPERUSER !!\n”

export PS1=`hostname`’:$PWD# ‘

############################# The End ##############################

#!/sbin/sh

######################## /sbin/init.d/inetd #######################

PATH=/sbin:/usr/sbin:/usr/bin

export PATH

rval=0

set_return() {

        x=$?

        if [ $x -ne 0 ]; then

                echo “EXIT CODE: $x”

                rval=1  # always 1 so that 2 can be used for other
reasons

        fi

}

case “$1” in

start_msg)

   echo “Start Internet services  daemon” ;;

stop_msg)

   echo “Stopping Internet services daemon” ;;

‘start’)

   if [ -f /etc/rc.config ]; then

      . /etc/rc.config

   else

      echo “ERROR: /etc/rc.config defaults file MISSING”

   fi

   mask=`umask`

   umask 000

   [ -x /usr/sbin/inetd ] && /usr/sbin/inetd $INETD_ARGS

   if [ $? -eq 0 ]; then

      echo “Internet Services started”

   else

      echo “Unable to start Internet Services”

   fi

   umask $mask

   ;;

‘stop’)

   if [ -f /etc/rc.config ]; then

      . /etc/rc.config

   else

      echo “ERROR: /etc/rc.config defaults file MISSING”

   fi

   /usr/sbin/inetd -k

   set_return

   if [ $rval -eq 0 ]; then

      echo “Internet Services stopped”

   else

      echo “Unable to stop Internet Services”

   fi

   ;;

*)

   echo “usage: $0 {start|stop}”

   rval=1

   ;;

esac

exit $rval

############################ The End ##############################3

#!/sbin/sh

############# /sbin/rc ################      

arg=$1

arg2=$2

PATH=/sbin

export PATH

/sbin/stty clocal icanon echo opost onlcr ixon icrnl ignpar 2>
/dev/null

umask 022

get_scripts() {

   state=$1

   mode=$2

   dir=/sbin/rc${state}.d

   ls $dir 2>/dev/null |

   while read name

   do

      case $name in

      ${mode}*)

         path=$dir/$name

         if [ “$mode” = “S” ]; then

            desc=`$path start_msg`

         elif [ “$mode” = “K” ]; then

            desc=`$path stop_msg`

         fi

         echo $path $desc

     esac

  done

}

if [ -f /sbin/rc.utils ]; then

   . /sbin/rc.utils

else

   init_list()

   {

      echo $1

   }

   add_list()

   {

      eval $1

   }

   run_list()

   {

      :

   }

fi

# If /etc/rc.config contains default information (first boot),

# /sbin/auto_parms will invoke /sbin/set_parms to remedy the situation.

# For 10.0 release, the default HOSTNAME is unset or an empty string.

# Assume a timezone if /etc/TIMEZONE does not exist.

TZ=EST5EDT

if [ -f /etc/rc.config ]; then

   . /etc/rc.config

   if [ -x /sbin/auto_parms ]; then

      /sbin/auto_parms

   else

      echo “\nWARNING: /sbin/auto_parms does not exist”

      echo “DHCP invocation skipped.”

   fi

else

   echo “\nWARNING: /etc/rc.config does not exist”

   echo “System name not set, default $TZ assumed.”

fi

export TZ

# Set runlevel information

set `who -r` x

new=$7         # new run level

old=$9         # previous run level

# Check to see if we are run from /etc/inittab, or from the command line.

# If run from the command line, set the old run-level to the new
run-level.

if [ $PPID != 1 ]; then

   old=$new

   # If the new run-level was specified on the command line,go to that
state

   # instead.

   if [[ -n $arg2 ]]; then

      new=$arg2

   fi

fi

if [ “$new” = S ]; then

   new=0

   tosingle=1

else

   tosingle=0

fi

BOOT=0

if [ “$old” = S ]; then

   old=0

   BOOT=1

fi

# Process scripts

found=0

if [ “$new” -gt “$old” ]; then

   # new run level is higher than old, so run start scripts in

   # all intermediate run levels and in new run level.

   if [ $BOOT = 1 ]; then

      init_list “HP-UX Start-up in progress”

   else

      init_list “Transition to run-level $new in progress”

   fi

   typeset -i lvl=$old

   lvl=lvl+1

   while [ $lvl -le “$new” ]; do

      get_scripts $lvl S |

      while read name descrip; do

         if [ -s “$name” ]; then

            add_list “$name start” “$descrip”

            found=1

         fi

      done

      lvl=lvl+1

   done

elif [ “$new” -lt “$old” ]; then

   # new run level is lower than old level, so run kill scripts

   # in all intermediate levels and in new level.

   if [ “$new” = 0 ]; then

      init_list “System shutdown in progress”

   else

      init_list “Transition to run-level $new in progress”

   fi

   typeset -i lvl=$old

   lvl=lvl-1

   while [ $lvl -ge “$new” ]; do

      get_scripts $lvl K |

      while read name descrip; do

         if [ -s “$name” ]; then

            add_list “$name stop” “$descrip”

            found=1

         fi

      done

      lvl=lvl-1

   done

   # If we’re ending up in state 0 or S, run the start scripts for

   # that state.

   if [ “$new” = 0 ]; then

      get_scripts 0 S |

      while read name descrip; do

         if [ -s “$name” ]; then

            add_list “$name start” “$descrip”

            found=1

         fi

      done

   fi

else

   # old and new run levels are the same.  Assume that execution

   # is from the command line and run start scripts for the current

   # run level

   init_list “Starting subsystems for run-level $new”

   get_scripts ${new} S |

   while read name descrip; do

      if [ -s “$name” ]; then

         add_list “$name start” “$descrip”

         found=1

      fi

   done

fi

if [ $found = 1 ]; then

   if [ “$BOOT” = 1 ]; then

      run_list boot

   else

      run_list

   fi

fi

if [ “$new” = 0 ]; then

   case $arg in

   “shutdown”)

      exec /sbin/sh

      ;;

   “reboot”)

      /sbin/reboot

      ;;

   “off”)

      /sbin/reboot -h

      ;;

   esac

   #If transitioned to real state 0 (that is, not state S) via init,
halt.

   if [[ $PPID -eq 1 && “$tosingle” -ne 1 ]]; then

      /sbin/reboot -h

   fi

fi

# Output message to indicate completion

echo

if [ $BOOT = 1 ]; then

   echo “The system is ready.”

else

   echo “Transition to run-level $new is complete.”

fi

############################## The End #################################3

#!/sbin/sh

##################### /sbin/init.d/net ##########################

#

# net:  configure lan interface(s) at initialization time.

# /etc/rc.config.d/netconf defines the configuration parameters:

#

# INTERFACE_NAME[i]:      network interface name (e.g., lan0)

# IP_ADDRESS[i]:          IP address of your system in decimal dot format

# SUBNET_NETMASK[i]:     subnetwork mask in decimal dot format

# BROADCAST_ADDRESS[i]:  broadcast address (other than default) in
decimal

#                             format

# LANCONFIG_ARGS[i]:      lanconfig(1m) options (e.g., ieee, ether)

# LOOPBACK_ADDRESS:       loopback address (always 127.0.0.1)

#

# ROUTE_DESTINATION[i]:  route destination

# ROUTE_MASK[i]:       subnet mask

# ROUTE_GATEWAY[i]:       local or remote IP address of gateway

# ROUTE_COUNT[i]:         zero for local gateway, one for remote gateway

# ROUTE_ARGS[i]:          route command options and arguments

#

###########################################################################

set +u  

export PATH=/sbin:/usr/sbin:$PATH

NETCONF=/etc/rc.config.d/netconf

NETSTAT_DATA=/var/adm/netstat_data

OKAY=0

ERROR=1

WARNING=2

# $1 = name of array

# return highest array element index in env; return -1 if no elements

function maxindex {

   # find only lines that start with “var[…]=”, grab only the number

   # between “[…]”, and print only the last one.

   # we would like to use `sed` as follows:

   #    typeset i=$(set | sed -n ‘s/^’$1’\[\([[:digit:]]\{1,\}\)\]=.*$/\1/p’

   #                | tail -1)

   # but it is not guaranteed to be in a mounted file system at this
time.

   typeset line

   typeset i=-1

   set | while read line; do

      # strip “var[” and “]=…”, leaving only number between “[…]”

      line=${line#*$1\[}

      line=${line%%\]=*}

      # if line is all digits, we found “var[…]=…”,

      # and line is string between “[…]”

      if [[ -n $line && -z ${line##*([[:digit:]])} ]]; then

         i=$line

      fi

   done

   print — $i

   return 0

}

##########

#  main   #

##########

case $1 in

start_msg)

   print “Configure LAN interfaces”

   exit $OKAY

   ;;

stop_msg)

   print “Unconfigure LAN interfaces”

   exit $OKAY

   ;;

stop)

   exit $OKAY

   ;;

start)

   ;;  # fall through

*)

   print “USAGE: $0 {start_msg | stop_msg | start | stop}” >&2

   exit $ERROR

   ;;

esac

###########

#  start  #

###########

# Remove the existing /var/adm/netstat_data file.  The first time

# netstat is executed, a new /var/adm/netstat_data file will be

# created.

rm -f $NETSTAT_DATA

# Get actual configuration

if [[ -f $NETCONF ]]; then

   . $NETCONF               # display any errors

   if (($? != 0)); then

      # NB: this is not working as expected:  status is not propagated!

      print “ERROR:   Incorrect data in the file $NETCONF.” >&2

      exit $ERROR

   fi

else

   print “ERROR:   Missing the file $NETCONF.” >&2

   exit $ERROR

fi

rval=$OKAY

# Do ifconfig and lanconfig commands for each interface

# `foo=$(print $foo)` collapses whitespace, remove surrounding whitespace

# We can have __fewer__ IP_ADDRESSes than INTERFACE_NAMEs (interfaces to
be

# ignore).  We can also have __fewer__ SUBNET_MASKs, BROADCAST_ADDRESSes
and

# LANCONFIG_ARGS (defaulted).  But we cannot have __more__.

# sanity check

nIF=$(maxindex INTERFACE_NAME)

if (($(maxindex IP_ADDRESS) > nIF)) || \

   (($(maxindex SUBNET_MASK) > nIF)) || \

   (($(maxindex BROADCAST_ADDRESS) > nIF)) || \

   (($(maxindex LANCONFIG_ARGS) > nIF))

then

   print “WARNING: Missing INTERFACE_NAME for corresponding IP_ADDRESS,
SUBNET_MASK,” >&2

   print ”         BROADCAST_ADDRESS or LANCONFIG_ARGS in the file”
>&2

   print ”         $NETCONF.  Excess variables will be ignored.”
>&2

   rval=$WARNING

fi

i=0

while ((i <= nIF)); do

   NAME=$(print ${INTERFACE_NAME[i]})

   INTERFACE_NAME[i]=$NAME          # without whitespace for route tests
below

   IP=$(print ${IP_ADDRESS[i]})

   IP_ADDRESS[i]=$IP                 # without whitespace for route tests
below

   if [[ $IP = “RARP” ]]; then

      IP=`/usr/sbin/rarpc $NAME`

      IP_ADDRESS[i]=$IP              # without whitespace for route tests
below

   fi

   if [[ -n $NAME && -n $IP ]]; then

      MASK=$(print ${SUBNET_MASK[i]})

      [[ -n “$MASK” ]] && MASK=”netmask $MASK”

      BCAST=$(print ${BROADCAST_ADDRESS[i]})

      [[ -n “$BCAST” ]] && BCAST=”broadcast $BCAST”

      PROTO=$(print ${LANCONFIG_ARGS[i]})    # do not set PROTO to any
default

      emsg=$(ifconfig $NAME $IP $MASK $BCAST up 2>&1)

      status=$?

      if ((status == 0)) && [[ -n $PROTO ]] ; then

         emsg=$(lanconfig $NAME $PROTO 2>&1)

         status=$?

      fi

      if ((status != 0)); then

         print “ERROR:   $NAME interface: $emsg” >&2

         rval=$ERROR

      fi

   fi

   let i=i+1

done

IP=$(print $LOOPBACK_ADDRESS)

if [[ -n $IP ]]; then

   emsg=$(ifconfig lo0 $IP up 2>&1)

   if (($? != 0)); then

      print “ERROR:   lo0 interface: $emsg” >&2

      rval=$ERROR

   fi

else

   print “ERROR:   Missing LOOPBACK_ADDRESS in the file $NETCONF.”
>&2

   print ”         lo0 interface not initialized.” >&2

   rval=$ERROR

fi

# Do route command for each configured route

# Note:  ${IP_ADDRESS[i]} must have whitespace removed already (above)

# We must have the __same__ number of ROUTE_GATEWAYs as
ROUTE_DESTINATIONs.

# But we can have __fewer__ ROUTE_COUNTs and ROUTE_MASKs (defaulted).

n=$(maxindex ROUTE_DESTINATION)

if (($(maxindex ROUTE_GATEWAY) != n)) || \

   (($(maxindex ROUTE_COUNT) > n))

then

   print \

      “WARNING: Missing ROUTE_DESTINATION for corresponding ROUTE_GATEWAY”
>&2

   print ”         or ROUTE_COUNT in the file $NETCONF.” >&2

   print ”         Excess variables will be ignored.” >&2

   rval=$WARNING

fi

i=0

while ((i <= n))

do

   DEST=$(print ${ROUTE_DESTINATION[i]})

   GWAY=$(print ${ROUTE_GATEWAY[i]})

   if [[ -n $DEST && -n $GWAY ]]; then

      COUNT=$(print ${ROUTE_COUNT[i]})

      if [[ -z $COUNT ]]; then

         # default COUNT:  if GWAY is one of the local interface IP

         # addresses, count is 0; otherwise, count is 1.

         COUNT=1

         k=0

         while ((k <= nIF)); do

            if [[ $GWAY = ${IP_ADDRESS[k]} && -n ${INTERFACE_NAME[k]}
]]; then

               COUNT=0

               break;

            fi

            let k=k+1

         done

      fi

      ARGS=${ROUTE_ARGS[i]}

      MASK=$(print ${ROUTE_MASK[i]})

      if [[ -z $MASK ]]; then

          # No subnet mask

          if [[ -z $ARGS ]]; then

             # No arguments

             emsg=$(route add $DEST $GWAY $COUNT 2>&1)

          else

             # With arguments

             emsg=$(route $ARGS add $DEST $GWAY $COUNT 2>&1)

          fi

      else

         # Subnet mask has been entered.

         if [[ -z $ARGS ]]; then

            # No arguments

            emsg=$(route add $DEST netmask $MASK $GWAY $COUNT
2>&1)

         else

            # With arguments

            emsg=$(route $ARGS add $DEST netmask $MASK $GWAY $COUNT
2>&1)

         fi

      fi

      # ignore “entry in use” errors.  these can arise because we

      # booted via NFS diskless, which added routes already

      if (($? != 0)) && [[ -n ${emsg##*entry in use*} ]]; then

         print “ERROR:   $emsg” >&2

         rval=$ERROR

      fi

   fi

   let i=i+1

done

# add loopback route for local interfaces to improve performance

k=0

while ((k <= nIF))

do

   if [[ -n ${IP_ADDRESS[k]} && -n ${INTERFACE_NAME[k]} ]]; then

      emsg=$(route add ${IP_ADDRESS[k]} $LOOPBACK_ADDRESS 0 2>&1)

      if (($? != 0)) && [[ -n ${emsg##*entry in use*} ]]; then

         print “ERROR:   $emsg” >&2

         rval=$ERROR

      fi

   fi

   let k=k+1

done

exit $rval

##################### The End  ###########################

1. Shell Program 소개

u      Shell 종류

/usr/bin/sh      POSIX Shell

/usr/bin/ksh     Korn Shell

/usr/old/bin/sh  Bourne Shell

/usr/bin/csh     C Shell

/usr/bin/keysh   Key Shell

/usr/bin/rksh    Restricted Korn Shell

/usr/bin/rsh     Restricted Shell

u      Shell Startup 파일

Korn Shell     /etc/profile -> $HOME/.profile -> $HOME/.kshrc

Bourne Shell   /etc/profile -> $HOME/.profile

POSIX Shell    /etc/profile -> $HOME/.profile -> $HOME/.kshrc

C Shell        $HOME/.login -> $HOME/.cshrc

2.Shell Parameter

u      Parameter Substitution

l         Parameter Setting

# Parameter=Value

# 변수명=값  : Named Parameter

l         Parameter의 Unsetting

# unset parameter

  # unset 변수명

u        Command Substitution

# $(command)       # `command`

# XX=”12345″

# echo $XX

12345

# HOST=‘hostname‘

# echo $HOST     : # HOST=`hostname` 문장은 # HOST=$(hostname)과 같다

ssosvr3           : 즉, `command` 문장과 $(command)는 같은 뜻이다

# PS1=‘hostname‘’:$PWD# ‘

# PS1=$(hostname)’:$PWD# ‘; echo $PS1

ssosvr3:/#

# W1=”A”; W2=”B”; W3=”C”

# WORD=${W1}AA${W2}BB${W3}CC

# echo $WORD

AAABBBCCC

# unset WORD

– $10과 ${10}은 다르다. 왜냐하면 $10은 positional parameter $1값에

   0값이 붙여서 출력되며, ${10}은 positional parameter 10번째의 값을

   나타내기 때문이다.

u        Positional Parameter(위치변수)

shell-script  arg1  arg2  arg3  arg4

$0               $1    $2     $3    $4

Positional Parameter : $1,$2,$3,$4

$0          shell script명을 나타낸다

$1          첫번째 argument를 나타낸다. 즉, arg1

$2          두번째 argument를 나타낸다. 즉, arg2

$*          “arg1 arg2 arg3 arg4 …” 즉,모든 argument와 같다.

$@          “arg1” “arg2” “arg3” “arg4…” 즉,개개의 argument와 같다.

$#          모든 argument의 갯수

$?          마지막으로 수행된 명령어가 return한 값

$$          현재 shell script를 수행하고 있는 shell의 process id(pid)

$!          현재shell에서 수행한 마지막 background의 pid

$_          shell command의 마지막 argument를 가르키며,shell start시에는

            shell의 절대 PATH를 가르킨다.

# set aaa bbb ccc ddd eee fff 

– set명령어를 옵션없이 사용하면 positional parameter를 setting한다.

# echo $0      sh   현재shell를 나타낸다.

# echo $1      aaa

# echo $#      5    $# 은 argument의 개수를 나타낸다.

# echo $*      “aaa bbb ccc ddd eee fff”

# echo $@      “aaa” “bbb” “ccc” “ddd” “eee”

– “$*” 와 “$@” 의 차이점은 $*은 Positional parameter의 모든값을 하나의

  문자열(string)으로 취급하며 $@ 는 string을 개개의 문자열로 취급한다.

# echo $$    7637   : shell의 process id

${parameter}           parameter의 값. 이것은 {}뒤에 붙어있는 문자나

                       숫자,_ 와 같은문자와 함께 사용할 때 필요하다.

${#parameter}          parameter값의 문자수. ${#*}나 ${#@}은 positional

                       parameter의 개수를 나타낸다.

${#identifier[*]}             배열 identifier에서 element의 수를 출력한다.

${parameter:-word}     parameter가 set되고 NOT NULL이면 parameter값을 출력하고,

                       그렇지 않으면 word의 값을 출력한다.

${parameter:+word}     parameter가 set되고 NOT NULL이면 word의 값을 출력하고,

                       그렇지 않으면 아무것도 출력하지 않는다.

${parameter:=word}     parameter가 set되고 NOT NULL이면 parameter의 값을

                       출력하고, 그렇지 않으면 word의 값을 출력하고 parameter에

                       word의 값을 assign한다. Positional parameter는

                       이렇게 setting할 수 없다.

${parameter:?word}     parameter가 set되고 NOT NULL이면 parameter값을

                       출력하고, 그렇지 않으면 word를 출력하고 shell를

                       exit한다. word가 생략되면 화면에 표준출력된다.

# dir1=/home/tmp

# echo ${dir1:-/usr/bin}

/home/tmp

# unset X

# echo ${X:-“X is unset”}

X is unset   : X가 unset또는 null이면 word가 출력된다.

# echo ${dir1:+/usr/bin}

/usr/bin     : dir1이 null이면 아무것도 출력되지 않는다.

# echo ${dir1:=/usr/bin}

/home/tmp    : dir1이 unset되었거나 null이라면 /usr/bin이 출력된다.

# echo ${dir1:?/usr/bin}

/home/tmp

# echo ${#dir1}

10               : /users/tmp 의 총 문자갯수

${parameter#pattern}   pattern이 parameter값의 첫문자와 같으면 그문자를

${parameter##pattern}  포함한 부분은 delete된다. ##은 wild card(*)시 사용함.

   

${parameter%pattern}   pattern이 parameter값을 끝문자와 같으면 그문자를

${parameter%%pattern}  포함한 문자는 delete된다. %%은 wild card(*)시 사용함.

# XX=/a/b/c/d/a/b

# echo ${XX#*a}

/b/c/d/a/b

# echo ${XX##*a}

/b

# echo ${XX%a*}

/a/b/c/d/

# echo ${XX%%a*}

/

# AA=”12345123″

# echo ${AA#1}

2345123

# echo ${AA##*1}

23

# echo ${AA%3}

1234512

# echo ${AA%%3*}

12

# echo ${AA#5}

12345123

# echo ${AA##*5}

123

# echo ${AA##*3*}

# echo ${AA##6*}

12345123

u        Tilde(~) Substitution

만약 user mary의 home directory가 /users/mary라면

# echo $HOME

/users/mary

# echo ~           : ~ 는 user의 home directory를 나타낸다.

/users/mary

# echo $PWD

/users/mary/tmp

# ls ~+/x*         : ~ 다음의 + 는 현재directory 즉, $PWD의 값을 가르킨다.

/users/mary/tmp/x_file1

/users/mary/tmp/x_file2

# echo $OLDPWD

/users/mary/mail

# ls ~-/f*         : ~ 뒤의 – 는 이전 directory 즉, $OLDPWD의 값을 가르킨다.

/users/mary/mail/from.mike 

/users/mary/mail/from.nick

u        Shell Command Grouping

l         ( command )  : subshell grouping

                 shell은 마치 또다른 script를 call한것처럼 subshell

                 환경에서 command를 수행한다.

l         { command ;} : brace grouping

                    shell은 현재의 shell 환경에서 연속해서command를

수행하며 마지막에 반드시 ;(세미콜론)을 써야한다.

# vi test1.sh

#! /usr/bin/sh

# (command)의 Example

A=”aaa”

B=”bbb”

C=”ccc”

( A=”AAA”

B=”BBB”

C=”CCC”

echo “PID $$ :

      $A $B $C” )

echo “PID $$ :

       $A $B $C”

:wq

# sh test1.sh

PID 28999 : AAA BBB CCC

PID 28999 : aaa bbb ccc

# vi test2.sh

#! /usr/bin/sh

# {command;}의 Example

A=”aaa”

B=”bbb”

C=”ccc”

{ A=”AAA”

B=”BBB”

C=”CCC”

echo “PID $$ :

      $A $B $C” ;}

echo “PID $$ :

       $A $B $C”

:wq

# sh test2.sh

PID 28955 : AAA BBB CCC

PID 28955 : AAA BBB CCC

u        Shell Script의 수행

# sh shell_script

# ksh shell_script

# chmod 777 shell_script

# ./shell_scipt

u        Shell Script Comment

l         shell script에서 comment는 첫라인에 # symbol를 넣는다.

l         shell script에서 첫라인의 #! /usr/bin/sh의 의미는 이 shell은

    Posix shell로 수행한다는 의미이다.

u        Input and Output

stdin(0)         standard input으로서 default는 keyboard이며

                 file descriptor값은 0 이다.

stdout(1)        standard output으로서 default는 terminal display이다.

                 file descriptor값은 1 이다.

stderr(2)        standard error로서 default는 terminal displsy이다.

                 file descriptor값은 2 이다.

<word            표준입력(file descriptor 0)으로 word를 사용한다.

>word            표준출력(file descriptor 1)으로 word를 사용하며,

word라는 file이 생성된다.

>|word           >word와 같으며 noclobber옵션이 설정되있어도 무조건 overwrite한다.

>>word           word라는 file이 존재하면 file에 append한다.

없으면 word라는file을 생성한다.

<>word           word를 입력으로 받아서 다시 word라는 file로 출력한다.

<<word           shell prompt에서 word라는 글자를 만날때까지 command를 입력할 수

                 있으며 word라는 글자를 만나면 shell command가 수행된다.

<&숫자           file descriptor 숫자의 file에서 data를 입력받는다.

>&숫자           file descriptor숫자를 가진 file로 출력한다.

<&-              표준입력을 close하여 keyboard로부터 입력받지 못한다.

>&-              표준출력을 close하여 terminal로 출력하지 않는다.

# ftp -n -i << AAA

>open mars

>user root password

>cd /users

>mget *

>close

AAA

#

# vi datafile       : data file작성

aaa

bbb

ccc

:wq

# vi read.sh

exec 5< datafile  : datafile을 file descriptor 5번으로 open한다.

read -u5 X        : 첫라인을 read하여 X변수에 assign한다.

read -u5 Y         : 둘째라인을 read하여 Y변수에 할당.

read -u5 Z        : 셋째라인을 read하여 Z변수에 할당.

exec 5<&-         : file descriptor 5번 file을 close한다.

echo “$X $Y $Z”   : file descriptor은 3-9까지 쓸수있다.

:wq

# sh read.sh

aaa bbb ccc

u        조건 표현식

test 또는 [ … ]             Integer,string.file등에 모두사용(old syntax)

(( … ))              Integer에만 사용(new syntax)

[[ … ]]              string,file에만 사용(new syntax)

l         String 표현식  # man test 참조

   
—————————————————————————-

[ -b file ]            file이 존재하고 block special file이면 참

[ -c file ]            file이 존재하고 character special file이면 참

[ -d file ]            file이 존재하고 directory이면 참

[ -e file ]            file이 존재하면 참

[ -f file ]            file이 존재하고 ordinary file이면 참

[ -g file ]            file이 존재하고 setgid bit가 set되있으면 참

[ -h file ]            file이 존재하고 symbolic link되었으면 참

[ -k file ]            file이 존재하고 sticky bit가 set되었으면 참

[ -p file ]            file이 존재하고 fifo special file또는 pipe이면 참

[ -r file ]            file이 존재하고 readable하면 참

[ -s file ]            file이 존재하고 file size가 0보다 크면 참

[ -u file ]            file이 존재하고 setuid bit가 set되 있으면 참

[ -w file ]            file이 존재하고 writable하면 참

[ -x file ]            file이 존재하고 executable하면 참

[ -L file ]            file이 존재하고 symbolic link이면 참

[ -O file ]            file이 존재하고 user가 effective user id와 같으면 참

[ -G file ]            file이 존재하고 group이 effective group id와 같으면 참

[ -S file ]            file이 존재하고 socket이면 참

—————————————————————————–

[ -n string ]          string의 길이가 non zero면 참

[ -z string ]          string의 길이가 zero이면 참

[ string ]                    string이 not null string이면참

# if [ -f /etc/rc.config ] ; then

# if [ ! -d /usr/bin ] ; then

# if [ -z “$NODENAME” ] ; then

# if [ -x /usr/dt/bin/dtrc ] ; then

# if [[ -n “$NAME” ]] ; then

# if [[ -s /var/spool/lp/pstatus ]] ; then

# if [[ -r /var/run/mrouted.pid ]] ; then

# if [[ -z “$pid” ]] ; then

# if /usr/sbin/envd ; then

# if /sbin/local_is_root ; then

# if [ “$ARRAYMON_PID” ] ; then

# if [ “$START_OV500” ] ; then

[ file1 -nt file2 ]    file1이 존재하고 file2보다 newer이면 참

[ file1 -ot file2 ]    file1이 존재하고 file2보다 older이면 참

[ file1 -ef file2 ]    file1이 존재하고 file2와 equal file이면 참

# if [ /sbin/init.d/spa –nt /sbin/init.d/set_date ] ; then

# if [ /aaa –ot /bbb ] ; then

# if [ /ccc –ef /ddd ] ; then

[ string1 = string2 ]  string1과 string2가 같으면 true

[ string1 = pattern ]  string1과 pattern이 같으면 true

[ string1 != string2 ] string1과 string2가 같지않으면 true

[ string1 != pattern ] string1과 pattern이 같지않으면 true

[ string1 < string2 ]  string1이 string2보다 작으면 true

[ string1 > string2 ]  string1이 string2보다 크면 true

# if [ “$pid” = “” ] ; then

# if [ X$pid != “X” ] ; then

# if [ $HOST != `hostname` ] ; then

# if [ “$MWASTART” > “1” ] ; then

# if [[ $? = 255 ]] ; then

[ exp1 -eq exp2 ]             exp1과 exp2가 같으면 참(equal)

[ exp1 -ne exp2 ]             exp1과 exp2가 같지 않으면 참(not equal)

[ exp1 -lt exp2 ]             exp1이 exp2보다 작으면 참(less than)

[ exp1 -gt exp2 ]             exp1이 exp2보다 크면 참(greater than)

[ exp1 -le exp2 ]             exp1이 exp2보다 작거나 같으면 참(less than or equal)

[ exp1 -ge exp2 ]             exp1이 exp2보다 크거나 같으면 참(greater than or
equal)

# if [ $x –ne 0 ] ; then

# if [ $? –eq 0 ] ; then

# if [ “$RWHOD” –eq 1 ] ; then

# if [[ “$rval” –eq ${EXIT_NA} ]] ; then

# while [ ${CNT} –le ${MAX_NISCHECKS} ] ; then

# if [ $# -ge 0 ] ; then

# if [ “$XX” –gt “$YY” ] ; then

# if [ “$X” –lt 1 ] ; then

# if [ $# -ne 1 ] ; then

# if [ `grep $HOSNAME /etc/mail/sendmail.cw|wc –l` -eq 0 ] ; then

( expression )         expression이 참이면 참

! expression           Binary NOT 연산자

exp –a exp2            Binary AND 연산자, 우선순위가 –o 보다 높음.

exp –o exp2            Binary OR 연산자

exp1 && exp2           exp1과 exp2가 모두 참이면 참

exp1 || exp2           exp1가 참이거나 exp2가 참이면 참

# if [ “$GATED” –eq 0 –a “X$pid” = “X” ] ; then

# if [ “$CRON” –eq 1 –a –x /usr/sbin/cron ] ; then

# if [ “$NIS_DOMAIN” –a –f /usr/bin/domainname ] ; then

# if [ “$NIS_MASTER” –ne 0 –o “$NIS_SLAVE” –ne 0 ] ; then

# if [ “$9” = ‘S’ ] || [ “$9” –lt ‘2’ ] ; then

# if [ “$VTDAEMON_START” –eq 1 ] && [ -x /usr/sbin/vtdaemon ] ;
then

# if [[ -r /usr/sbin/swagentd# ]] && [[ -h /usr/sbin/swagentd ]] ;
then

# if [ $status !=2 –o –z “$DOMAIN” –o –z “$SERVER” ] ; then

# if (( status == 0 )) && [[ -n $PROTO ]] ; then

l         Integer 표현식

(( integer1 == integer2 ))    integer1과 integer2가 같으면 참

(( integer1 != integer2 ))    integer1과 integer2가 같지 않으면 참

(( integer1 < integer2 ))           integer1이 integer2보다 작으면 참

(( integer1 > integer2 ))           integer1이 integer2보다 크면 참

(( integer1 <= integer2 ))    integer1이 integer2보다 작거나 같으면 참

(( integer1 >= integer2 ))    integer1이 integer2보다 크거나 같으면 참

# if (( $? != 0 )) ; then

# while ((n>0))

# if ((n<2) || !length(part[2])) ; then

# if ( $1 != mypid ) ; then

# if (( $1 > $2 )) ; then

3.Shell Programming

u        if 조건문

if 조건문

then

   명령어

[elif 조건문

then

   명령어]

[else

   명령어]

fi

if 조건문; then 명령어; [elif 조건문; then 명령어;] [else 명령어;] fi

:wq# vi if1.sh

X=hello

if [ $X = hello ]

then

   echo “Welcome”

else

   echo “Goodbye”

fi

:wq

# sh if1.sh

Welcome

# vi if2.sh

if [ -f temp ]

then

   mv temp temp1

elif [ -f temp1 ]

then

   mv temp1 temp2

fi

:wq

# sh if2.sh

u        case 조건문

case 변수 in

변수값1|변수값2…)

   명령어;;

변수값3|변수값4…)

   명령어;;

*)

   명령어;;

esac

#  vi case.sh

case $1 in

-d|-r)

        rmdir $dir1

        echo “directory removed” ;;

-o)

        echo “option -o” ;;

*)     

        echo “Invalid option,Try again…” ;;

esac

:wq

# chmod 777 case1.sh

# ./case.sh -o

option -o

u        while 반복문

while 조건문

do

   명령어

done

– 다음은 모두 같은 while문이다.

while [ 1 ]

do

  echo “Test”

done

while true

do

  echo “Test”

done

while [ : ]

do

  echo “Test”

done

while :

do

  echo “Test”

done

# vi while1.sh

count=$(who|grep -v root|wc -l)

while [ “$count” -gt 0 ]

do

   echo “Users still logged in…”

   sleep 1

   count=$(who|grep -v root|wc -l)

done

:wq

# sh while1.sh

# vi while2.sh

# /usr/bin/sh

#

print -n “Enter a value : “

read Value

print “Thank You”

count=0

while [ “$count” -lt “$Value” ]

do

   (( count=count + 1 ))

   print “Still sleeping for the $count th time…”

   sleep 2

done

print “End of $0”

:wq

# sh while2.sh

u        for 반복문

for 변수 [in 변수값1,변수값2,…]

do

   명령어

done

# vi for1.sh

for name in $(cut -d -f1 /etc/passwd)

do

   mailx $name < message.txt

   echo “Mail sent to $name”

done

:wq

# sh for1.sh

# vi for2.sh

if [[ ! -d “$1” ]]

then

   exit 1

fi

filename=$(ls $1)

for onefile in $filename

do

   if [[ -f ${1}/$onefile ]]

   then

      ll ${1}/$onefile

   elif [[ -d ${1}/$onefile ]]

   then

      ll -d ${1}/$onefile

   fi

done

:wq

# sh for2.sh /etc

u        until 반복문

until 조건문

do

   명령어

done

# vi until.sh

count=$(who|grep -v root|wc -l)

until [ “$count” -eq 0 ]

do

   echo “Users still logged in…”

   sleep 1

   count=$(who|grep -v root|wc -l)

done

:wq

# sh until.sh

u        select 반복문

select 변수 [in 변수값1,변수값2,…]

do

   명령어

done

– select문은 PS3 prompt를 사용한다. PS3 shell 변수의 기본값은 #? 이다.

– 변수는 변수값1,변수값2,… 등이 할당된다.

– 입력된 변수의 값의 숫자는 REPLY라는 shell변수에 저장된다.

– exit,return,break 등의 명령어로 반복문을 빠져나올수 있다.

– [in 변수값1,변수값2,…]가 없을경우에는 Positional Parameter를 사용한다.

# vi edit.sh         ### Edit the file ###

select menu in $(ls) “Exit” ; do

   case $menu in

     Exit) exit;;

     “”) echo “Invalid selection. Try again!”;;

     *) cp $menu $menu.bak; vi $menu ;;

   esac ; done

:wq

# vi color.sh

  select color in red blue green

  do

     echo “$color is an $color color”

     echo “$REPLY is a REPLY value”

  done

:wq

# sh color.sh

1)red

2)blue

3)green

#? 1

red is an red color

1 is a PEPLY value

#? 2

blue is an blue color

2 is a REPLY value

#? ^C

#

# vi select.sh

PS3=”Enter your choice =>”

select menu in “full backup”

                  “partial backup”

do

 case $menu in

 “full backup”)

  fbackup –0uf /dev/rmt/0m –i /stand

  echo “Full backup has begun”

  exit 0;;

 “Partial backup”)

fbackup –0uf /dev/rmt/0m -i /opt

echo “Partial Backup has begun”

return;;

 *) echo “$REPLY is an invalid

             option. Try again!”;;

 esac

done

:wq

# sh select.sh

# vi nest.sh

  #### Nested Select Command Example ###

#! /usr/bin/sh

PS3=”Main Choice by number=>”

select menu in “List Files” “Exit”

do

   case $menu in

   “List Files”)

      PS3=”Sub Choice by number=>”

      select ls_option in “Short” “Long” “Main”

      do

         case $ls_option in

          “Short”) lsf;;

           “Long”) ll;;

           “Main”)

               PS3=”Main Choice by number=>”  ## Restore Prompt

               break 1 ;;  ## exit inner loop

           “”) echo “$REPLY is an invalid option. Try again!”;;

         esac

      done ;;

   “Exit”) exit;;

   “”) echo “$REPLY is an invalid option. Try again!”;;

   esac

done

:wq

# sh nest.sh

u        Function(함수)

function 함수명

{

  shell script

}

함수명()

{

  shell script

}

– shell script안에 선언할수도 있고 밖에 선언할수도 있다.

– 함수명이나 argument로 called될수 있다.

– 같은 process를 반복적으로 사용할때 유리하며 debugging하기가 쉽다.

– typeset -xf name 으로 함수명을 export하여 global 함수로 선언할수 있다.

# vi func1.sh

function exef

{

   if [ -x $1 ]

   then

      echo “$1 is executable”

   fi

}

for file in `ls`

do

   exef $file

done

:wq

# sh func1.sh

# vi func2.sh

Uppercase()

{

   echo $* | tr “[a-z]””[A-Z”]”

}

print -n “Enter in a string:”

read string

upper_string=$(Uppercase $string)

echo “The uppercase string is: $upper_string”

:wq

# sh func2.sh

# vi func3.sh       : Recursive Fuction

bottom_up

{

   typeset SAVEPWD

   echo “\nDirectory being listed is: $PWD\n”

   lsf

   if [ “$PWD” != “/” ]

   then

      SAVEPWD=$PWD

      cd ..

      bottom_up

      cd $SAVEPWD

   else

      echo “That’s the end!”

   fi

}

:wq

# sh func3.sh

u        Array(배열)

– shell script에서 사용할수 있는 배열은 1차원배열이다.

– 배열요소(element)는 최대 512-1024까지 쓸수 있다.

– 배열요소는 [0]부터 [1023]까지 쓸수 있다.

– Array subscript인 [N]에서 N은 integer또는 integer expression을 쓸수 있다.

# X[0]=first

# X[1]=second

# X[2]=third

# echo ${X[1]}

second

# echo ${X}         : ${X}는 ${X[0]}과 같음

first

# echo ${X[*]}             : ‘*’나 ‘@’는 모든 요소를 가르킴

first second third

# echo ${#X[*]}

3

# i=3

# X[2*(i+1)]=10

# print ${X[8]

10

# set -A YY 100 200 300    : set -A는 변수를 배열로 선언한다.

# print ${YY[0]} ${YY[1]} ${YY[2]}

100 200 300

# set +A YY 150

# print ${YY[@]}

150 200 300

4.Shell Command

u        : 명령어

– ‘:’ 명령어는 아무것도 수행하지 않으며, 어떤 영향도 미치지 않는다. ‘0’값이 return됨.

# vi xx.sh

if [ -f /opt ]; then

   ls

else

   :            아무것도 수행하지 않는다.

fi

:wq

u        . 명령어

# . /etc/profile

– /etc/profile이라는 프로그램을 수행한다. 이는 sh나 ksh처럼 또하나의 shell을 fork하여

  프로그램을 수행하지 않으며 이 프로그램은 수행가능한 permission이 없어도 된다.

  즉 이 파일은 ‘x’ permission이 없어도 된다.

u        alias 명령어

alias [-x] [ name[=value] … ]

# alias                             : 현재 setting된 모든 alias를 display

# alias a=alias

# a x=lsf

# alias i=’

> echo Users logged in are:

> who|sort

> echo I am `whoami`’

# i                                  : alias문을 수행한다.

# unalias i                        : alias변수 i를 unsetting한다.

# unalias -a                       : shell command에서 typing한 모든

                                        alias를 해제한다.

# alias -x who=’who|sort’       : Korn shell에서 who를 export하여

                                        subshell에서도 사용가능하다.

u        break 명령어

break [n]

– for,while,until,select문과 같은 반복문에서 exit할 때 사용한다.

– n을 쓰면 n레벨만큼 loop를 exit한다.

# vi break.sh

for file in x y z none

do

   if [ -x $file ]; then

      echo $file

      break

   fi

done

:wq

u        command 명령어

command [arg …]

– argument를 command로서 취급한다.

# command lsf       : lsf를 command로 사용한다.

# command aaa       : aaa를 command로 사용한다.

u        continue 명령어

continue [n]

– for,while,until,select문과 같은 반복문에서 continue이하의 문을 수행하지 않고

다시 시작한다.

    – n을 쓰면 n번째 반복문을 다시 시작한다.

# vi con.sh

for file in x y z

do

   if [ -x $file ]; then

      continue

      echo “$file is executable”

   fi

   echo $file is not executable

done

:wq

u        echo 명령어

echo [arg …]

# echo ‘This is a’ $var ‘example.’

# echo “This is a $var example.”

# echo “Enter your user name: \c”

> read user

> echo ‘User is’ $user

echo 에서 Escape Character

\b     backspace

\c     continue line. new line을

       하지 않고 계속 붙여서 print한다

\f     form feed

\n     new line

\r     carriage return

\t     tab

\v     vertival tab

\\     backslash

u        eval 명령어

eval [arg …]

– argument를 input으로 받아서 명령어로 수행하며 argument는 command나 shell

  script가 될수 있다.

# cmd=’ps -ef > ps.out’

# eval $cmd

# eval “grep jones $file|set|echo $1 $2 $3”

u        exec 명령어

exec [arg …]

– 새로운 process나 subshell을 만들어서 argument를 수행하지 않고 현재 shell로

  명령어를 바로 수행한다.

# exec 3< file          file desciptor number 3으로 file을 open한다.

# ecec 2> /dev/null     표준에러를 /dev/null로 출력한다.

u        expr 명령어         # man expr 참조

expr expression {+,-,\*,/} expression

expr expression {=,\>,\>=,\<,\<=,!=} expression

expr string1 : string2

# a=15

# expr $a + 5

20

# count=`expr $count + 5`

# A=batman

# expr substr $A 1 3

bat

# expr index $A m

4

u        fc 명령어

fc [-r] [-e example] [first [last]]

fc –l [-nr] [first [last]]

fc –s [old=new] [first]

fc –e – [old=new] [command]

– fc command는 history file을 list하거나 history file에서 command를 edit할 수있다.

# fc –l            : history file의 내용을 display한다.

# fc –l 20 25

# fc –l 10

# fc –e vi 15 20

# fc –e –          : 방금 실행한 command를 다시 실행한다. # r 명령과 같다.

# fc –e – ls=cd  

u        let 명령어

let “expression”

(( expression ))

– let는 산술 표현을 가능하게 하며 long integer 계산을 한다.

Operator

Description

!

/  %

+  –

<  <=  >  >=

==  !=

=

unary minus

logical negation

곱하기,나누기,몫

더하기,빼기

비교

같다,같지 않다

변수 할당

# x=10

# y=2

# let x=x+2

# echo $x

12

# let “x=x/(y+1)”

# echo $x

4

# (( x=x+1 ))

# echo $x

5

# x=12

# let “x<10”

# echo $?

1

# (( x > 10 ))

# echo $?

0

# if (( x > 10 ))

>then echo x greater

>else echo x not greater

>fi

x greater

u        read 명령어

read [-r] name…        : POSIX Shell only

read [-prsu] [name]    : Korn Shell only

-r          라인연속으로 쓰인 라인끝의 \를 해석하지 않는다.

-un         file descriptor n 으로부터 input을 read한다.

# vi read.sh

  while read -r xx yy

  do

     printf “%s %s \n” “$yy” “$xx”

done < input_file

:wq

u        return 명령어

return [n]

– 함수의 실행을 마치고 calling shell script에게 exit status n을 return한다.

– n이 없으면 return status는 함수의 마지막 command의 값이다.

– return이 함수의 밖에서 수행되면 exit로서 실행된다.

# vi return.sh

  search()

  {

     if grep xxx “$1” > /dev/null 2>&1

     then return 1

     else return 2

     fi

  }

:wq

# sh return.sh filename

u      set 명령어

l         Positional Parameter값 setting

# set spring summer fall winter

# echo $3

fall

# echo $*

spring summer fall winter

l         Positional Parameter Sorting

# set third first second

# echo $1 $2 $3

third first second

# set –s               : 값을 lexical order로 sorting함

# echo $1 $2 $3

first second third

# set +s            : unsetting

option         option-name meaning

——————————————————————————–

set –a         allexport   모든 parameter가 자동으로 export됨. == set -o
allexport

set -C         noclobber   #date>XX시 >로 overwrite하지못하게 함. date>|XX로는
가능

set –e         errexit     shell command fail시 즉시 logout또는 shell을 exit함

set –f         noglob             # ls * 시wild card문자를 인식못함

set –h         trackall   

set –k         keyword    

set –m         monitor     Background jogs이 각각다른 process group에서 수행되고

                           작업이 끝나면 message를 report함

set –o                     set –o monitor와 같이 option-name에 붙여서 옵션을

                           setting함

set –s                     positional parameter를 sort함

set –t                     shell을 exit한후에 command를 수행함

set –u         nounset     substituting시 unset parameter를 error로 취급함

set –v         verbose     command를 display한후 command 수행

set –x         xtrace             command수행시 command와 argument까지 print함.

                           shell script의 debug mode로 사용함.

              

set                        현재 setting된 모든 shell variable을 list함

set –                      -x와 –v option을 turn off하고 flag에 대한 argument

                           검사를 하지 않음

set —                     옵션의 어떤 변화도 하지못하게 함. # set — -;echo $1

                                      file명으로 시작하는 file을 rm할 경우 # set — -;rm
–aaa

# set –o ignoreeof          : ignoreeof라는 옵션을 turn on

# set +o vi                : vi의 옵션을 turn off

# set –o noglob            : noglob옵션을 turn on 시키고 wild card인

                                    *,[],-,!,? 등을 shell이 해석하지 못하게함

# set –o noexec            : shell의 syntax error를 check하기위해 사용.

                             이 옵션은 interactive shell에서는 사용되지

                                    않으며 shell script에서만 수행됨.

                             noexec 옵션은 실제로 shell을 수행하지 않으면서

                                       shell의 syntax error만을 check하는
명령어다.

# vi set1.sh

  set –o noexec

  echo “This is test

  ls

  cp /aaa /bbb

:wq

# ksh set1.sh

set1.sh: syntax error at line 2 : ‘”‘ unmatched

# vi set2.sh

  set –x

  ls

  echo “The Test”

  set +x

  lsf

:wq

# sh set2.sh

u        shift 명령어

shift [n]

shift command는 positional parameter($1,$2,$3..)의 내용을 왼쪽순으로 move한다.

# vi shift1.sh

  yflag=0

  zopt=””

  for arg in “$@”

  do

     if [ “x$arg” = x-y ]

     then

        yflag=1

        shift

     else

       zopt=”$2″

       shift 2

     fi

  done

:wq

u        trap 명령어

trap [command] [signal]

– signal 값은 # kill –l또는 # man kill 명령어로 볼수 있음.

# trap “echo ‘Command Failed'” 2

                       : ^C(interupt)를 치면 echo 문장이 수행됨.

# trap              : trap 명령을 수행한후 옵션이 없이 trap명령을 수행하면 현재

                    setting된 모든 trap내용을 보여줌

# trap “” 1 2 3

                       : 1}HUP 2)INT 3)QUIT가 입력되도 무시하라.

# trap “echo logout” 0

                       : signal이 ‘0’ 이면 NULL signal로서

                         shell에서 exit할때 command가 수행된다.

u      typeset 명령어

typeset [-][+]옵션  변수명[=변수값]

option      meaning

—————————————————————————–

[-]         변수명의 속성을 setting

[+]         변수명의 속성을 turn off

-Ln         왼쪽의 공백을 제거하고 왼쪽에서 n숫자만큼 cut

-Rn         왼쪽에 공백을 채우고 오른쪽에서 n숫자만큼 cut

-Z          오른쪽으로 shift하고, 첫번째 문자가 숫자이고 –L옵션과 같이

            쓰지 않았으면 왼쪽에 숫자0을 채움

-i          변수명을 integer로 선언

-f          변수명이 아니라 함수명으로 변수를 선언

-l          모든 영문대문자를 소문자로 변환

-u          모든 소문자를 대문자로 변환

-r          변수를 read-only로 만듬,즉 변수를 상수로 만듬

-x          변수를 export함, 즉 변수를 전역변수로 만듬

—————————————————————————–

# typeset

현재 setting되어있는 변수의 data type을 보여줌

# typeset AA

AA변수를 string변수로 선언,또한 함수내에서 Local변수 즉 지역변수로 선언

하지만, shell에서 변수는 default로 string data type임

# DATA=”Today we had very HOT weather”

# typeset –u DATA

# echo $DATA

TODAY WE HAD VERY HOT WEATHER

# typeset +u DATA : DATA변수의 속성을 turn off 

# DATA=”as of the “${DATA}

# echo $DATA

as of the TODAY WE HAD VERY HOT WEATHER

# AAA=123456789

# typeset –L3 AAA

# echo $AAA

123

# typeset –LZ X=00005

# print $X

5

# typeset –i X        : 변수X를  integer로 선언 # integer X와 같음

# typeset –i2 X     : 변수X를 2진수로 선언

# typeset –i8 X     : 변수X를 8진수로 선언

# typeset –i10 X    : 변수X를 10진수로 선언

# typeset –i16 X    : 변수X를 16진수로 선언

# typeset -r Y=123  : 변수Y를 readonly변수로 선언 # readonly Y=123과 같음

# typeset -f        : 모든함수와 그 값을 display함

# typeset -xf       : export된 모든함수와 그 값을 display함

# typeset -xf XX    : 함수명 XX를 export하여 global function으로 선언함

u        ulimit 명령어

ulimit  [-f] [n]

– ulimit command는 child process나 subprocess에 의해 사용된는 resources를 제한한다.

# ulimit               : 현재 limit값을 보여준다

# ulimit –f 1000       : 현재process나 향후 process가 write할 수 있는

                          file size를 1000 block(1000*512 byte)으로 제한한다.

# ulimit –f unlimited : child process가 생성할 수 있는 size의 제한을 없앤다.

5.Regular Expression(정규 수식)

u        Pattern Matching과 Regular Expression의 비교 – # man 5 regexp참조

Pattern Matching

Regular Expression

– POSIX shell에서 사용

– file name생성과 case문에서 사용

– UNIX command와 Text Editor에서 사용

  (ed,vi,ex,sed,awk,expr,grep)

– file name을 match한다

– character string을 match한다

– file name을 substitute한다

– string을 search해서 substitute한다

– 사용되는 특수문자

  ?,  *,  [ – ],  !

– 사용되는 특수문자

  .,  [],  -,  ^,  $,  *

u        하나의 문자와 Match – .(dot)

A.          : AB,Ab,AA,A9등과 같이 A다음에오는 어느한문자와 match

…         : 연속된 3문자와 match

# man 5 regexp|col -b|expand > regexp.man

# grep ‘RE.’ regexp.man       : RE다음에오는 어느한문자와 Match되는 라인만 출력

u        문자의 시작과 Match – ^

^abc        : 첫문자가 abc로 시작되는 문자와 match. abc,abcabc,abcdef등과 match

^C          : 문자의 시작에서 C와 match

^C$         : 하나의 문자 C와 match

^.$         : 하나의 문자로만 구성된 문자와 match

^[ABC]      : 첫문자가 ABC로 시작되는 문자와 match

u        문자의 끝과 Match – $

abc$        : 끝문자가 abc로 끝나는 문자와 match. defgabc,cccabc,abc등과 match

^…$       : 3개의 문자로만 구성된 문자와 match

\.$         : 문자의 끝에서 마침표(.)과 match

\*$         : 문자의 끝에서 (*)와 match

u        문자 Match – []

[Tt]he      : The나 the라는 글자를 search

h[iau]t     : hit,hat,hut의 글자와 match

[ABC]       : A,B,C를 포함하는 문자와 match

u        범위를 포함하는 문자와 Match – [ – ]

[a-z]       : 소문자 a부터 z까지 어느문자와도 match

[0-9]        : 0-9까지 어떤 하나의 숫자와 match

[0-57]      : 0,1,2,3,4,5,7과 match

[a-c5-8X-Z] : a,b,c,5,6,7,8,X,Y,Z중 하나의 문자와 match

[0-3-]      : 0,1,2,3,-와 match

u        Complemented문자 Match – [^  ]

[^ ]        : 공백이 아닌 한문자와 match

[^0-9]      : 0-9까지 숫자가 아닌 하나의 모든문자와 match

[^a-zA-Z]   : 영문 알파벳이 아닌 문자나 숫자와 match

[012^]      : 0,1,2,^와 match

^[^a-z]$    : 소문자을 제외한 나머지 문자중 하나와 match

# man 5 regexp|col -b|expand > regexp.man

# grep ‘^$’ regexp.man|wc -l         : 공백라인수를 출력한다.

# TMOUNT=`/sbin/mount | grep ‘^/tmp(/| )’ | wc -l`

# grep -q -e “^/usr/bin$” -e “^/usr/bin:” -e “:/usr/bin:”\

         -e “:/usr/bin$” /etc/PATH

u        Null 또는 여러 같은문자와 Match – *,+,?

B*          : Null문자,B,BB,BBB…등과 match

AB*C        : AC,ABC,ABBC…등과 match

A+          : A,AA,AAA…등과 match

AB+C        : ABC,ABBC,ABBBC…등과 match

A?          : Null문자 또는 A와 match

AB?C        : AC,ABC와 match

[A-Z]+      : 하나이상의 대문자와 match

(AB)        : AB문자와 match

(AB)+C      : ABC,ABABC,ABABABC…등과 match

AB.*XYZ     : ABXYZ,ABCXYZ,ABCCCCXYZ…등과 match

u        특수문자 Match – \

\*          : 특수문자 *와 match

\$          : 특수문자 $와 match

\\          : 특수문자 \와 match

\\\\\.\*$   : 문자의 끝에서 \\.* 와 match

u        Subexpression – \( … \)

– \(…\)구문을 사용한다.

– subexpression과 match하는 문자를 recall하기위해 ‘\숫자’를 사용한다.

– ‘\숫자’ 는 1-9까지 쓸수있다.

– \1 은 1번째 subexpression,\2 는 2번째 subexpression을 나타낸다.

# who

root       console      Oct 23 13:01

root       ttyp1        Oct 27 12:45

root       pts/0        Oct 22 09:03

# who|sed ‘s/\([^ ][^ ]*\)[^A-Z][^A-Z]*\(.*\)/\2–>\1/’

Oct 23 13:01–>root

Oct 27 12:45–>root

Oct 22 09:03–>root

– 첫번째 /\([^ ][^ ]*\) 는 공백이 아닌 하나이상의 문자와 match하며 뒷부분의

  \1 의 값과 같다.즉, 여기서는 username root를 가르킨다.

– 두번째 \(.*\) 는 최초로 대문자로 시작되는 문자와 match하며 뒷부분의

  \2 의 값과 같다. 여기서는 Oct를 가르킨다.

6.Sed(Stream Editor)

u        sed 형식

sed [-n] command input_file…

sed [-n] [-e command]… [-f script_file]… [input_file…]

-n          화면에 display하지 않는다. 단  p명령어일경우는 화면에 display한다.

            -n옵션은 -e나 -f옵션중 하나와 같이 사용할수 있다.

-e command  command를 editing하며, input file이 없으면 표준입력이 사용된다.

-f script   input file에서 editing command의 script file을 수행한다.

– sed는 입력파일로부터 한라인씩 data를 read한다.

– sed는 default로 화면에 출력을 하며 input file을 modify하지 않는다.

# sed “s/UNIX/Unix/g” file1 > file2.new

# sed -e “s/Miss/Ms/g” -e “s/Mrs/Ms/g” file2

# sed -n “1,10p” file2

# cat script

1,10p

# sed -n -f script file2

u        s(substitute)

[address [,address]] s/string_old/string_new/[flag]

flag        meaning

g           global substitution(전라인을 모두바꾼다)

p           print line

w file      file로 write한다

# sed “s/[Cc]omputer/COMPUTER/g” file1

# sed -e “1,5s/abc/xyz/” -e ‘s/kbs/mbc/’ file1 > file2

# sed “/abcde/s/ab/AB/g” file1

# sed -e ‘s/abc/xyz/w file2’ file1

# sed “3s/the/xyz/g” file1

# sed ‘3s/^the /xyz/’ file1

# sed -e “/the/s/ for /xyz/g

# cat file1| sed “/the/s/ for /xyz/gw file2

# sed “1,8s/aaa/bbb/g” file1 > file2

# sed “/^5/,/^15/s/from/FROM/g”

# sed -e “/^The first time/,/^End of file/s/lsf/ll/g”

# sed “1,$s/\/usr\/bin/\/sbin\/bin/g”

u        d(delete)

# sed “1,10d” fileA

   – fileA에서 1-10라인까지 delete한다.

# sed “/^From/!d” mbox

   – mbox file에서 From으로 시작되는 라인만 제외하고 모두 delete한다.

u        p(print),l(list),=,q(quit),r(read),w(write)

p           standard output에 print한다. -n옵션과 함께써도 print된다.

l           nonprinting문자도 같이 표준출력한다.

=           address 라인의 라인번호를 표준출력한다.

q           현재라인을 출력하고 sed를 종료한다.

r file      file의 내용을 read하여 표준출력한다.

w file      file에 address라인을 write또는 append한다.

# vi cap

   One potato, teo potato,

   three potato, four.

   Five potato, six potato,

   seven potato, more.

:wq

# sed -n “1,2p” cap

One potato, two potato,

three potato, four.

# sed -e “q” cap

One potato, teo potato,

# sed -e “/\./=” -e ” /[A-Z]/w file1″ cap

One potato, teo potato,

2

three potato, four.

Five potato, six potato,

4

seven potato, more.

# killproc() {

      for x in “$@”

      do

         pid=`ps -e |grep “$x” |sed -e ‘s/^  *//’ -e ‘s/ .*//’`

         [ ! –z “$pid” ] && echo killing $x && kill $pid
&

      done

  }

# findproc() {

    pid=`ps –e |grep “$1” |sed -e ‘s/^  *//’ -e ‘s/ .*//’`

    echo $pid

  }

# killproc() {           

      echo stopping $1

      pid=`/usr/bin/ps -e |

            /usr/bin/grep “$1” |

            /usr/bin/sed -e ‘s/^  *//’ -e ‘s/ .*//’`

            [ “$pid” != “” ] && kill $pid

  }

# if [ “$RWHOD” –ne 1 ]; then

      rval=2

  else

      pid=`ps -el | awk ‘( ($NF ~ /rwhod/) && ($4 != mypid)
&&

           ($5 != mypid)) { print $4 }’ mypid=$$ `

      if [ “X$pid” != “X” ]; then

         if kill $pid; then

            echo “rwhod stopped”

         else

            rval=1

            echo “Unable to stop rwhod”

         fi

      fi

  fi

#

#

#

# ARRAYMON_PID=`ps -ef | awk ‘$0 ~ /.*arraymon*/ && $0 !~
/.*awk.*/

                  { print $2 }’`

  if [ “$ARRAYMON_PID” ]

  then

     echo “Killing disk array monitor daemon.”

     kill -9 $ARRAYMON_PID

     sleep 2

     ARRAYMON_PID=`ps -ef | awk ‘$0 ~ /.*arraymon*/ && $0 !~
/.*awk.*/

                     { print $2 }’`

     if [ “$ARRAYMON_PID” ]

     then

       echo “ERROR:  Could not kill ${ARRAY_MONITOR_DAEMON}”

     fi

  fi

#

7.Shell Program 예제

-shell script를 위한 data file은 다음과 같다.

# vi data

  100 200 300 400

  500 600 700 800

  900 1000 1100 1200

  1300 1400 1500 1600

  1200 800 400 0

:wq

# vi exp1.sh

if [[ ! -f “$1” ]]

then

   echo “${0##*/}”

   exit 1

else

   filename=$1

fi

exec 3< $filename : file descriptor 3으로 filename를 open

typeset -i II=0   : XX를 integer로 선언

while read -u3 AA[0] AA[[1] AA[2] AA[3]

do

   for II in 0 1 2 3

   do

      (( total[II]=${total[II]} + ${AA[II]} ))

   done

print “Subtotal : “

print ${total[*]}

done

print “Total for the four columns are : “

print ${total[@]}

:wq

# sh exp1.sh

#!/usr/bin/sh

######################## /etc/profile ##########################  

trap “” 1 2 3                   

PATH=/usr/bin:/usr/ccs/bin:/usr/contrib/bin

MANPATH=/usr/share/man:/usr/contrib/man:/usr/local/man

if [ ! -d /usr/sbin ]

then

   PATH=$PATH:/sbin

else

   if [ -r /etc/PATH ]

   then

      grep -q -e “^/usr/bin$” -e “^/usr/bin:” -e “:/usr/bin:”\

                -e “:/usr/bin$” /etc/PATH

      if [ $? -eq 0 ]

      then

         PATH=`cat /etc/PATH`

      else

         PATH=$PATH:`cat /etc/PATH`

      fi

   fi

fi

export PATH

if [ -r /etc/MANPATH ]

then

   MANPATH=`cat /etc/MANPATH`

fi

export MANPATH

if [ -r /etc/TIMEZONE ]

then

   . /etc/TIMEZONE 

else

   TZ=MST7MDT       

   export TZ

fi

if [ ! “$VUE” ]; then

   if [ “$TERM” = “” -o “$TERM” = “unknown” -o “$TERM” = “dialup”  \

                         -o “$TERM” = “network” ]

   then

      eval `ttytype -s -a`

   fi

   export TERM

   if [ “$ERASE” = “” ]

   then

      ERASE=”^H”

      export ERASE

   fi

   stty erase $ERASE

   trap “echo logout” 0

   cat /etc/copyright

   if [ -r /etc/motd ]

   then

      cat /etc/motd

   fi

   if [ -f /usr/bin/mail ]

   then

      if mail –e

      then echo “You have mail.”

      fi

   fi

   if [ -f /usr/bin/news ]

   then news –n

   fi

   if [ -r /tmp/changetape ]

   then

      echo “\007\nYou are the first to log in since backup:”

      echo “Please change the backup tape.\n”

      rm -f /tmp/changetape

   fi

fi

trap 1 2 3

###################### The End ##########################

#!/usr/bin/sh

############# /.profile ################  

set +u

PATH=/usr/sbin:$PATH:/sbin:/home/root

if [ ! “$VUE” ]; then

   if [ “$TERM” = “” ]

   then

      eval ` tset -s -Q -m ‘:?hp’ `

   else

      eval ` tset -s -Q `

   fi

   stty erase “^H” kill “^U” intr “^C” eof “^D” susp “^Z”

   stty hupcl ixon ixoff

   tabs

   echo

   echo “Value of TERM has been set to \”$TERM\”. “

   export TERM

   EDITOR=vi

   export EDITOR

fi

set –u

trap “echo ‘logout root'” 0

MAIL=/var/mail/root

echo “WARNING:  YOU ARE SUPERUSER !!\n”

export PS1=`hostname`’:$PWD# ‘

############################# The End ##############################

#!/sbin/sh

######################## /sbin/init.d/inetd #######################

PATH=/sbin:/usr/sbin:/usr/bin

export PATH

rval=0

set_return() {

        x=$?

        if [ $x -ne 0 ]; then

                echo “EXIT CODE: $x”

                rval=1  # always 1 so that 2 can be used for other
reasons

        fi

}

case “$1” in

start_msg)

   echo “Start Internet services  daemon” ;;

stop_msg)

   echo “Stopping Internet services daemon” ;;

‘start’)

   if [ -f /etc/rc.config ]; then

      . /etc/rc.config

   else

      echo “ERROR: /etc/rc.config defaults file MISSING”

   fi

   mask=`umask`

   umask 000

   [ -x /usr/sbin/inetd ] && /usr/sbin/inetd $INETD_ARGS

   if [ $? -eq 0 ]; then

      echo “Internet Services started”

   else

      echo “Unable to start Internet Services”

   fi

   umask $mask

   ;;

‘stop’)

   if [ -f /etc/rc.config ]; then

      . /etc/rc.config

   else

      echo “ERROR: /etc/rc.config defaults file MISSING”

   fi

   /usr/sbin/inetd -k

   set_return

   if [ $rval -eq 0 ]; then

      echo “Internet Services stopped”

   else

      echo “Unable to stop Internet Services”

   fi

   ;;

*)

   echo “usage: $0 {start|stop}”

   rval=1

   ;;

esac

exit $rval

############################ The End ##############################3

#!/sbin/sh

############# /sbin/rc ################      

arg=$1

arg2=$2

PATH=/sbin

export PATH

/sbin/stty clocal icanon echo opost onlcr ixon icrnl ignpar 2>
/dev/null

umask 022

get_scripts() {

   state=$1

   mode=$2

   dir=/sbin/rc${state}.d

   ls $dir 2>/dev/null |

   while read name

   do

      case $name in

      ${mode}*)

         path=$dir/$name

         if [ “$mode” = “S” ]; then

            desc=`$path start_msg`

         elif [ “$mode” = “K” ]; then

            desc=`$path stop_msg`

         fi

         echo $path $desc

     esac

  done

}

if [ -f /sbin/rc.utils ]; then

   . /sbin/rc.utils

else

   init_list()

   {

      echo $1

   }

   add_list()

   {

      eval $1

   }

   run_list()

   {

      :

   }

fi

# If /etc/rc.config contains default information (first boot),

# /sbin/auto_parms will invoke /sbin/set_parms to remedy the situation.

# For 10.0 release, the default HOSTNAME is unset or an empty string.

# Assume a timezone if /etc/TIMEZONE does not exist.

TZ=EST5EDT

if [ -f /etc/rc.config ]; then

   . /etc/rc.config

   if [ -x /sbin/auto_parms ]; then

      /sbin/auto_parms

   else

      echo “\nWARNING: /sbin/auto_parms does not exist”

      echo “DHCP invocation skipped.”

   fi

else

   echo “\nWARNING: /etc/rc.config does not exist”

   echo “System name not set, default $TZ assumed.”

fi

export TZ

# Set runlevel information

set `who -r` x

new=$7         # new run level

old=$9         # previous run level

# Check to see if we are run from /etc/inittab, or from the command line.

# If run from the command line, set the old run-level to the new
run-level.

if [ $PPID != 1 ]; then

   old=$new

   # If the new run-level was specified on the command line,go to that
state

   # instead.

   if [[ -n $arg2 ]]; then

      new=$arg2

   fi

fi

if [ “$new” = S ]; then

   new=0

   tosingle=1

else

   tosingle=0

fi

BOOT=0

if [ “$old” = S ]; then

   old=0

   BOOT=1

fi

# Process scripts

found=0

if [ “$new” -gt “$old” ]; then

   # new run level is higher than old, so run start scripts in

   # all intermediate run levels and in new run level.

   if [ $BOOT = 1 ]; then

      init_list “HP-UX Start-up in progress”

   else

      init_list “Transition to run-level $new in progress”

   fi

   typeset -i lvl=$old

   lvl=lvl+1

   while [ $lvl -le “$new” ]; do

      get_scripts $lvl S |

      while read name descrip; do

         if [ -s “$name” ]; then

            add_list “$name start” “$descrip”

            found=1

         fi

      done

      lvl=lvl+1

   done

elif [ “$new” -lt “$old” ]; then

   # new run level is lower than old level, so run kill scripts

   # in all intermediate levels and in new level.

   if [ “$new” = 0 ]; then

      init_list “System shutdown in progress”

   else

      init_list “Transition to run-level $new in progress”

   fi

   typeset -i lvl=$old

   lvl=lvl-1

   while [ $lvl -ge “$new” ]; do

      get_scripts $lvl K |

      while read name descrip; do

         if [ -s “$name” ]; then

            add_list “$name stop” “$descrip”

            found=1

         fi

      done

      lvl=lvl-1

   done

   # If we’re ending up in state 0 or S, run the start scripts for

   # that state.

   if [ “$new” = 0 ]; then

      get_scripts 0 S |

      while read name descrip; do

         if [ -s “$name” ]; then

            add_list “$name start” “$descrip”

            found=1

         fi

      done

   fi

else

   # old and new run levels are the same.  Assume that execution

   # is from the command line and run start scripts for the current

   # run level

   init_list “Starting subsystems for run-level $new”

   get_scripts ${new} S |

   while read name descrip; do

      if [ -s “$name” ]; then

         add_list “$name start” “$descrip”

         found=1

      fi

   done

fi

if [ $found = 1 ]; then

   if [ “$BOOT” = 1 ]; then

      run_list boot

   else

      run_list

   fi

fi

if [ “$new” = 0 ]; then

   case $arg in

   “shutdown”)

      exec /sbin/sh

      ;;

   “reboot”)

      /sbin/reboot

      ;;

   “off”)

      /sbin/reboot -h

      ;;

   esac

   #If transitioned to real state 0 (that is, not state S) via init,
halt.

   if [[ $PPID -eq 1 && “$tosingle” -ne 1 ]]; then

      /sbin/reboot -h

   fi

fi

# Output message to indicate completion

echo

if [ $BOOT = 1 ]; then

   echo “The system is ready.”

else

   echo “Transition to run-level $new is complete.”

fi

############################## The End #################################3

#!/sbin/sh

##################### /sbin/init.d/net ##########################

#

# net:  configure lan interface(s) at initialization time.

# /etc/rc.config.d/netconf defines the configuration parameters:

#

# INTERFACE_NAME[i]:      network interface name (e.g., lan0)

# IP_ADDRESS[i]:          IP address of your system in decimal dot format

# SUBNET_NETMASK[i]:     subnetwork mask in decimal dot format

# BROADCAST_ADDRESS[i]:  broadcast address (other than default) in
decimal

#                             format

# LANCONFIG_ARGS[i]:      lanconfig(1m) options (e.g., ieee, ether)

# LOOPBACK_ADDRESS:       loopback address (always 127.0.0.1)

#

# ROUTE_DESTINATION[i]:  route destination

# ROUTE_MASK[i]:       subnet mask

# ROUTE_GATEWAY[i]:       local or remote IP address of gateway

# ROUTE_COUNT[i]:         zero for local gateway, one for remote gateway

# ROUTE_ARGS[i]:          route command options and arguments

#

###########################################################################

set +u  

export PATH=/sbin:/usr/sbin:$PATH

NETCONF=/etc/rc.config.d/netconf

NETSTAT_DATA=/var/adm/netstat_data

OKAY=0

ERROR=1

WARNING=2

# $1 = name of array

# return highest array element index in env; return -1 if no elements

function maxindex {

   # find only lines that start with “var[…]=”, grab only the number

   # between “[…]”, and print only the last one.

   # we would like to use `sed` as follows:

   #    typeset i=$(set | sed -n ‘s/^’$1’\[\([[:digit:]]\{1,\}\)\]=.*$/\1/p’

   #                | tail -1)

   # but it is not guaranteed to be in a mounted file system at this
time.

   typeset line

   typeset i=-1

   set | while read line; do

      # strip “var[” and “]=…”, leaving only number between “[…]”

      line=${line#*$1\[}

      line=${line%%\]=*}

      # if line is all digits, we found “var[…]=…”,

      # and line is string between “[…]”

      if [[ -n $line && -z ${line##*([[:digit:]])} ]]; then

         i=$line

      fi

   done

   print — $i

   return 0

}

##########

#  main   #

##########

case $1 in

start_msg)

   print “Configure LAN interfaces”

   exit $OKAY

   ;;

stop_msg)

   print “Unconfigure LAN interfaces”

   exit $OKAY

   ;;

stop)

   exit $OKAY

   ;;

start)

   ;;  # fall through

*)

   print “USAGE: $0 {start_msg | stop_msg | start | stop}” >&2

   exit $ERROR

   ;;

esac

###########

#  start  #

###########

# Remove the existing /var/adm/netstat_data file.  The first time

# netstat is executed, a new /var/adm/netstat_data file will be

# created.

rm -f $NETSTAT_DATA

# Get actual configuration

if [[ -f $NETCONF ]]; then

   . $NETCONF               # display any errors

   if (($? != 0)); then

      # NB: this is not working as expected:  status is not propagated!

      print “ERROR:   Incorrect data in the file $NETCONF.” >&2

      exit $ERROR

   fi

else

   print “ERROR:   Missing the file $NETCONF.” >&2

   exit $ERROR

fi

rval=$OKAY

# Do ifconfig and lanconfig commands for each interface

# `foo=$(print $foo)` collapses whitespace, remove surrounding whitespace

# We can have __fewer__ IP_ADDRESSes than INTERFACE_NAMEs (interfaces to
be

# ignore).  We can also have __fewer__ SUBNET_MASKs, BROADCAST_ADDRESSes
and

# LANCONFIG_ARGS (defaulted).  But we cannot have __more__.

# sanity check

nIF=$(maxindex INTERFACE_NAME)

if (($(maxindex IP_ADDRESS) > nIF)) || \

   (($(maxindex SUBNET_MASK) > nIF)) || \

   (($(maxindex BROADCAST_ADDRESS) > nIF)) || \

   (($(maxindex LANCONFIG_ARGS) > nIF))

then

   print “WARNING: Missing INTERFACE_NAME for corresponding IP_ADDRESS,
SUBNET_MASK,” >&2

   print ”         BROADCAST_ADDRESS or LANCONFIG_ARGS in the file”
>&2

   print ”         $NETCONF.  Excess variables will be ignored.”
>&2

   rval=$WARNING

fi

i=0

while ((i <= nIF)); do

   NAME=$(print ${INTERFACE_NAME[i]})

   INTERFACE_NAME[i]=$NAME          # without whitespace for route tests
below

   IP=$(print ${IP_ADDRESS[i]})

   IP_ADDRESS[i]=$IP                 # without whitespace for route tests
below

   if [[ $IP = “RARP” ]]; then

      IP=`/usr/sbin/rarpc $NAME`

      IP_ADDRESS[i]=$IP              # without whitespace for route tests
below

   fi

   if [[ -n $NAME && -n $IP ]]; then

      MASK=$(print ${SUBNET_MASK[i]})

      [[ -n “$MASK” ]] && MASK=”netmask $MASK”

      BCAST=$(print ${BROADCAST_ADDRESS[i]})

      [[ -n “$BCAST” ]] && BCAST=”broadcast $BCAST”

      PROTO=$(print ${LANCONFIG_ARGS[i]})    # do not set PROTO to any
default

      emsg=$(ifconfig $NAME $IP $MASK $BCAST up 2>&1)

      status=$?

      if ((status == 0)) && [[ -n $PROTO ]] ; then

         emsg=$(lanconfig $NAME $PROTO 2>&1)

         status=$?

      fi

      if ((status != 0)); then

         print “ERROR:   $NAME interface: $emsg” >&2

         rval=$ERROR

      fi

   fi

   let i=i+1

done

IP=$(print $LOOPBACK_ADDRESS)

if [[ -n $IP ]]; then

   emsg=$(ifconfig lo0 $IP up 2>&1)

   if (($? != 0)); then

      print “ERROR:   lo0 interface: $emsg” >&2

      rval=$ERROR

   fi

else

   print “ERROR:   Missing LOOPBACK_ADDRESS in the file $NETCONF.”
>&2

   print ”         lo0 interface not initialized.” >&2

   rval=$ERROR

fi

# Do route command for each configured route

# Note:  ${IP_ADDRESS[i]} must have whitespace removed already (above)

# We must have the __same__ number of ROUTE_GATEWAYs as
ROUTE_DESTINATIONs.

# But we can have __fewer__ ROUTE_COUNTs and ROUTE_MASKs (defaulted).

n=$(maxindex ROUTE_DESTINATION)

if (($(maxindex ROUTE_GATEWAY) != n)) || \

   (($(maxindex ROUTE_COUNT) > n))

then

   print \

      “WARNING: Missing ROUTE_DESTINATION for corresponding ROUTE_GATEWAY”
>&2

   print ”         or ROUTE_COUNT in the file $NETCONF.” >&2

   print ”         Excess variables will be ignored.” >&2

   rval=$WARNING

fi

i=0

while ((i <= n))

do

   DEST=$(print ${ROUTE_DESTINATION[i]})

   GWAY=$(print ${ROUTE_GATEWAY[i]})

   if [[ -n $DEST && -n $GWAY ]]; then

      COUNT=$(print ${ROUTE_COUNT[i]})

      if [[ -z $COUNT ]]; then

         # default COUNT:  if GWAY is one of the local interface IP

         # addresses, count is 0; otherwise, count is 1.

         COUNT=1

         k=0

         while ((k <= nIF)); do

            if [[ $GWAY = ${IP_ADDRESS[k]} && -n ${INTERFACE_NAME[k]}
]]; then

               COUNT=0

               break;

            fi

            let k=k+1

         done

      fi

      ARGS=${ROUTE_ARGS[i]}

      MASK=$(print ${ROUTE_MASK[i]})

      if [[ -z $MASK ]]; then

          # No subnet mask

          if [[ -z $ARGS ]]; then

             # No arguments

             emsg=$(route add $DEST $GWAY $COUNT 2>&1)

          else

             # With arguments

             emsg=$(route $ARGS add $DEST $GWAY $COUNT 2>&1)

          fi

      else

         # Subnet mask has been entered.

         if [[ -z $ARGS ]]; then

            # No arguments

            emsg=$(route add $DEST netmask $MASK $GWAY $COUNT
2>&1)

         else

            # With arguments

            emsg=$(route $ARGS add $DEST netmask $MASK $GWAY $COUNT
2>&1)

         fi

      fi

      # ignore “entry in use” errors.  these can arise because we

      # booted via NFS diskless, which added routes already

      if (($? != 0)) && [[ -n ${emsg##*entry in use*} ]]; then

         print “ERROR:   $emsg” >&2

         rval=$ERROR

      fi

   fi

   let i=i+1

done

# add loopback route for local interfaces to improve performance

k=0

while ((k <= nIF))

do

   if [[ -n ${IP_ADDRESS[k]} && -n ${INTERFACE_NAME[k]} ]]; then

      emsg=$(route add ${IP_ADDRESS[k]} $LOOPBACK_ADDRESS 0 2>&1)

      if (($? != 0)) && [[ -n ${emsg##*entry in use*} ]]; then

         print “ERROR:   $emsg” >&2

         rval=$ERROR

      fi

   fi

   let k=k+1

done

exit $rval

##################### The End  ###########################

 소개

u      Shell 종류

/usr/bin/sh      POSIX Shell

/usr/bin/ksh     Korn Shell

/usr/old/bin/sh  Bourne Shell

/usr/bin/csh     C Shell

/usr/bin/keysh   Key Shell

/usr/bin/rksh    Restricted Korn Shell

/usr/bin/rsh     Restricted Shell

u      Shell Startup 파일

Korn Shell     /etc/profile -> $HOME/.profile -> $HOME/.kshrc

Bourne Shell   /etc/profile -> $HOME/.profile

POSIX Shell    /etc/profile -> $HOME/.profile -> $HOME/.kshrc

C Shell        $HOME/.login -> $HOME/.cshrc

2.Shell Parameter

u      Parameter Substitution

l         Parameter Setting

# Parameter=Value

# 변수명=값  : Named Parameter

l         Parameter의 Unsetting

# unset parameter

  # unset 변수명

u        Command Substitution

# $(command)       # `command`

# XX=”12345″

# echo $XX

12345

# HOST=‘hostname‘

# echo $HOST     : # HOST=`hostname` 문장은 # HOST=$(hostname)과 같다

ssosvr3           : 즉, `command` 문장과 $(command)는 같은 뜻이다

# PS1=‘hostname‘’:$PWD# ‘

# PS1=$(hostname)’:$PWD# ‘; echo $PS1

ssosvr3:/#

# W1=”A”; W2=”B”; W3=”C”

# WORD=${W1}AA${W2}BB${W3}CC

# echo $WORD

AAABBBCCC

# unset WORD

– $10과 ${10}은 다르다. 왜냐하면 $10은 positional parameter $1값에

   0값이 붙여서 출력되며, ${10}은 positional parameter 10번째의 값을

   나타내기 때문이다.

u        Positional Parameter(위치변수)

shell-script  arg1  arg2  arg3  arg4

$0               $1    $2     $3    $4

Positional Parameter : $1,$2,$3,$4

$0          shell script명을 나타낸다

$1          첫번째 argument를 나타낸다. 즉, arg1

$2          두번째 argument를 나타낸다. 즉, arg2

$*          “arg1 arg2 arg3 arg4 …” 즉,모든 argument와 같다.

$@          “arg1” “arg2” “arg3” “arg4…” 즉,개개의 argument와 같다.

$#          모든 argument의 갯수

$?          마지막으로 수행된 명령어가 return한 값

$$          현재 shell script를 수행하고 있는 shell의 process id(pid)

$!          현재shell에서 수행한 마지막 background의 pid

$_          shell command의 마지막 argument를 가르키며,shell start시에는

            shell의 절대 PATH를 가르킨다.

# set aaa bbb ccc ddd eee fff 

– set명령어를 옵션없이 사용하면 positional parameter를 setting한다.

# echo $0      sh   현재shell를 나타낸다.

# echo $1      aaa

# echo $#      5    $# 은 argument의 개수를 나타낸다.

# echo $*      “aaa bbb ccc ddd eee fff”

# echo $@      “aaa” “bbb” “ccc” “ddd” “eee”

– “$*” 와 “$@” 의 차이점은 $*은 Positional parameter의 모든값을 하나의

  문자열(string)으로 취급하며 $@ 는 string을 개개의 문자열로 취급한다.

# echo $$    7637   : shell의 process id

${parameter}           parameter의 값. 이것은 {}뒤에 붙어있는 문자나

                       숫자,_ 와 같은문자와 함께 사용할 때 필요하다.

${#parameter}          parameter값의 문자수. ${#*}나 ${#@}은 positional

                       parameter의 개수를 나타낸다.

${#identifier[*]}             배열 identifier에서 element의 수를 출력한다.

${parameter:-word}     parameter가 set되고 NOT NULL이면 parameter값을 출력하고,

                       그렇지 않으면 word의 값을 출력한다.

${parameter:+word}     parameter가 set되고 NOT NULL이면 word의 값을 출력하고,

                       그렇지 않으면 아무것도 출력하지 않는다.

${parameter:=word}     parameter가 set되고 NOT NULL이면 parameter의 값을

                       출력하고, 그렇지 않으면 word의 값을 출력하고 parameter에

                       word의 값을 assign한다. Positional parameter는

                       이렇게 setting할 수 없다.

${parameter:?word}     parameter가 set되고 NOT NULL이면 parameter값을

                       출력하고, 그렇지 않으면 word를 출력하고 shell를

                       exit한다. word가 생략되면 화면에 표준출력된다.

# dir1=/home/tmp

# echo ${dir1:-/usr/bin}

/home/tmp

# unset X

# echo ${X:-“X is unset”}

X is unset   : X가 unset또는 null이면 word가 출력된다.

# echo ${dir1:+/usr/bin}

/usr/bin     : dir1이 null이면 아무것도 출력되지 않는다.

# echo ${dir1:=/usr/bin}

/home/tmp    : dir1이 unset되었거나 null이라면 /usr/bin이 출력된다.

# echo ${dir1:?/usr/bin}

/home/tmp

# echo ${#dir1}

10               : /users/tmp 의 총 문자갯수

${parameter#pattern}   pattern이 parameter값의 첫문자와 같으면 그문자를

${parameter##pattern}  포함한 부분은 delete된다. ##은 wild card(*)시 사용함.

   

${parameter%pattern}   pattern이 parameter값을 끝문자와 같으면 그문자를

${parameter%%pattern}  포함한 문자는 delete된다. %%은 wild card(*)시 사용함.

# XX=/a/b/c/d/a/b

# echo ${XX#*a}

/b/c/d/a/b

# echo ${XX##*a}

/b

# echo ${XX%a*}

/a/b/c/d/

# echo ${XX%%a*}

/

# AA=”12345123″

# echo ${AA#1}

2345123

# echo ${AA##*1}

23

# echo ${AA%3}

1234512

# echo ${AA%%3*}

12

# echo ${AA#5}

12345123

# echo ${AA##*5}

123

# echo ${AA##*3*}

# echo ${AA##6*}

12345123

u        Tilde(~) Substitution

만약 user mary의 home directory가 /users/mary라면

# echo $HOME

/users/mary

# echo ~           : ~ 는 user의 home directory를 나타낸다.

/users/mary

# echo $PWD

/users/mary/tmp

# ls ~+/x*         : ~ 다음의 + 는 현재directory 즉, $PWD의 값을 가르킨다.

/users/mary/tmp/x_file1

/users/mary/tmp/x_file2

# echo $OLDPWD

/users/mary/mail

# ls ~-/f*         : ~ 뒤의 – 는 이전 directory 즉, $OLDPWD의 값을 가르킨다.

/users/mary/mail/from.mike 

/users/mary/mail/from.nick

u        Shell Command Grouping

l         ( command )  : subshell grouping

                 shell은 마치 또다른 script를 call한것처럼 subshell

                 환경에서 command를 수행한다.

l         { command ;} : brace grouping

                    shell은 현재의 shell 환경에서 연속해서command를

수행하며 마지막에 반드시 ;(세미콜론)을 써야한다.

# vi test1.sh

#! /usr/bin/sh

# (command)의 Example

A=”aaa”

B=”bbb”

C=”ccc”

( A=”AAA”

B=”BBB”

C=”CCC”

echo “PID $$ :

      $A $B $C” )

echo “PID $$ :

       $A $B $C”

:wq

# sh test1.sh

PID 28999 : AAA BBB CCC

PID 28999 : aaa bbb ccc

# vi test2.sh

#! /usr/bin/sh

# {command;}의 Example

A=”aaa”

B=”bbb”

C=”ccc”

{ A=”AAA”

B=”BBB”

C=”CCC”

echo “PID $$ :

      $A $B $C” ;}

echo “PID $$ :

       $A $B $C”

:wq

# sh test2.sh

PID 28955 : AAA BBB CCC

PID 28955 : AAA BBB CCC

u        Shell Script의 수행

# sh shell_script

# ksh shell_script

# chmod 777 shell_script

# ./shell_scipt

u        Shell Script Comment

l         shell script에서 comment는 첫라인에 # symbol를 넣는다.

l         shell script에서 첫라인의 #! /usr/bin/sh의 의미는 이 shell은

    Posix shell로 수행한다는 의미이다.

u        Input and Output

stdin(0)         standard input으로서 default는 keyboard이며

                 file descriptor값은 0 이다.

stdout(1)        standard output으로서 default는 terminal display이다.

                 file descriptor값은 1 이다.

stderr(2)        standard error로서 default는 terminal displsy이다.

                 file descriptor값은 2 이다.

<word            표준입력(file descriptor 0)으로 word를 사용한다.

>word            표준출력(file descriptor 1)으로 word를 사용하며,

word라는 file이 생성된다.

>|word           >word와 같으며 noclobber옵션이 설정되있어도 무조건 overwrite한다.

>>word           word라는 file이 존재하면 file에 append한다.

없으면 word라는file을 생성한다.

<>word           word를 입력으로 받아서 다시 word라는 file로 출력한다.

<<word           shell prompt에서 word라는 글자를 만날때까지 command를 입력할 수

                 있으며 word라는 글자를 만나면 shell command가 수행된다.

<&숫자           file descriptor 숫자의 file에서 data를 입력받는다.

>&숫자           file descriptor숫자를 가진 file로 출력한다.

<&-              표준입력을 close하여 keyboard로부터 입력받지 못한다.

>&-              표준출력을 close하여 terminal로 출력하지 않는다.

# ftp -n -i << AAA

>open mars

>user root password

>cd /users

>mget *

>close

AAA

#

# vi datafile       : data file작성

aaa

bbb

ccc

:wq

# vi read.sh

exec 5< datafile  : datafile을 file descriptor 5번으로 open한다.

read -u5 X        : 첫라인을 read하여 X변수에 assign한다.

read -u5 Y         : 둘째라인을 read하여 Y변수에 할당.

read -u5 Z        : 셋째라인을 read하여 Z변수에 할당.

exec 5<&-         : file descriptor 5번 file을 close한다.

echo “$X $Y $Z”   : file descriptor은 3-9까지 쓸수있다.

:wq

# sh read.sh

aaa bbb ccc

u        조건 표현식

test 또는 [ … ]             Integer,string.file등에 모두사용(old syntax)

(( … ))              Integer에만 사용(new syntax)

[[ … ]]              string,file에만 사용(new syntax)

l         String 표현식  # man test 참조

   
—————————————————————————-

[ -b file ]            file이 존재하고 block special file이면 참

[ -c file ]            file이 존재하고 character special file이면 참

[ -d file ]            file이 존재하고 directory이면 참

[ -e file ]            file이 존재하면 참

[ -f file ]            file이 존재하고 ordinary file이면 참

[ -g file ]            file이 존재하고 setgid bit가 set되있으면 참

[ -h file ]            file이 존재하고 symbolic link되었으면 참

[ -k file ]            file이 존재하고 sticky bit가 set되었으면 참

[ -p file ]            file이 존재하고 fifo special file또는 pipe이면 참

[ -r file ]            file이 존재하고 readable하면 참

[ -s file ]            file이 존재하고 file size가 0보다 크면 참

[ -u file ]            file이 존재하고 setuid bit가 set되 있으면 참

[ -w file ]            file이 존재하고 writable하면 참

[ -x file ]            file이 존재하고 executable하면 참

[ -L file ]            file이 존재하고 symbolic link이면 참

[ -O file ]            file이 존재하고 user가 effective user id와 같으면 참

[ -G file ]            file이 존재하고 group이 effective group id와 같으면 참

[ -S file ]            file이 존재하고 socket이면 참

—————————————————————————–

[ -n string ]          string의 길이가 non zero면 참

[ -z string ]          string의 길이가 zero이면 참

[ string ]                    string이 not null string이면참

# if [ -f /etc/rc.config ] ; then

# if [ ! -d /usr/bin ] ; then

# if [ -z “$NODENAME” ] ; then

# if [ -x /usr/dt/bin/dtrc ] ; then

# if [[ -n “$NAME” ]] ; then

# if [[ -s /var/spool/lp/pstatus ]] ; then

# if [[ -r /var/run/mrouted.pid ]] ; then

# if [[ -z “$pid” ]] ; then

# if /usr/sbin/envd ; then

# if /sbin/local_is_root ; then

# if [ “$ARRAYMON_PID” ] ; then

# if [ “$START_OV500” ] ; then

[ file1 -nt file2 ]    file1이 존재하고 file2보다 newer이면 참

[ file1 -ot file2 ]    file1이 존재하고 file2보다 older이면 참

[ file1 -ef file2 ]    file1이 존재하고 file2와 equal file이면 참

# if [ /sbin/init.d/spa –nt /sbin/init.d/set_date ] ; then

# if [ /aaa –ot /bbb ] ; then

# if [ /ccc –ef /ddd ] ; then

[ string1 = string2 ]  string1과 string2가 같으면 true

[ string1 = pattern ]  string1과 pattern이 같으면 true

[ string1 != string2 ] string1과 string2가 같지않으면 true

[ string1 != pattern ] string1과 pattern이 같지않으면 true

[ string1 < string2 ]  string1이 string2보다 작으면 true

[ string1 > string2 ]  string1이 string2보다 크면 true

# if [ “$pid” = “” ] ; then

# if [ X$pid != “X” ] ; then

# if [ $HOST != `hostname` ] ; then

# if [ “$MWASTART” > “1” ] ; then

# if [[ $? = 255 ]] ; then

[ exp1 -eq exp2 ]             exp1과 exp2가 같으면 참(equal)

[ exp1 -ne exp2 ]             exp1과 exp2가 같지 않으면 참(not equal)

[ exp1 -lt exp2 ]             exp1이 exp2보다 작으면 참(less than)

[ exp1 -gt exp2 ]             exp1이 exp2보다 크면 참(greater than)

[ exp1 -le exp2 ]             exp1이 exp2보다 작거나 같으면 참(less than or equal)

[ exp1 -ge exp2 ]             exp1이 exp2보다 크거나 같으면 참(greater than or
equal)

# if [ $x –ne 0 ] ; then

# if [ $? –eq 0 ] ; then

# if [ “$RWHOD” –eq 1 ] ; then

# if [[ “$rval” –eq ${EXIT_NA} ]] ; then

# while [ ${CNT} –le ${MAX_NISCHECKS} ] ; then

# if [ $# -ge 0 ] ; then

# if [ “$XX” –gt “$YY” ] ; then

# if [ “$X” –lt 1 ] ; then

# if [ $# -ne 1 ] ; then

# if [ `grep $HOSNAME /etc/mail/sendmail.cw|wc –l` -eq 0 ] ; then

( expression )         expression이 참이면 참

! expression           Binary NOT 연산자

exp –a exp2            Binary AND 연산자, 우선순위가 –o 보다 높음.

exp –o exp2            Binary OR 연산자

exp1 && exp2           exp1과 exp2가 모두 참이면 참

exp1 || exp2           exp1가 참이거나 exp2가 참이면 참

# if [ “$GATED” –eq 0 –a “X$pid” = “X” ] ; then

# if [ “$CRON” –eq 1 –a –x /usr/sbin/cron ] ; then

# if [ “$NIS_DOMAIN” –a –f /usr/bin/domainname ] ; then

# if [ “$NIS_MASTER” –ne 0 –o “$NIS_SLAVE” –ne 0 ] ; then

# if [ “$9” = ‘S’ ] || [ “$9” –lt ‘2’ ] ; then

# if [ “$VTDAEMON_START” –eq 1 ] && [ -x /usr/sbin/vtdaemon ] ;
then

# if [[ -r /usr/sbin/swagentd# ]] && [[ -h /usr/sbin/swagentd ]] ;
then

# if [ $status !=2 –o –z “$DOMAIN” –o –z “$SERVER” ] ; then

# if (( status == 0 )) && [[ -n $PROTO ]] ; then

l         Integer 표현식

(( integer1 == integer2 ))    integer1과 integer2가 같으면 참

(( integer1 != integer2 ))    integer1과 integer2가 같지 않으면 참

(( integer1 < integer2 ))           integer1이 integer2보다 작으면 참

(( integer1 > integer2 ))           integer1이 integer2보다 크면 참

(( integer1 <= integer2 ))    integer1이 integer2보다 작거나 같으면 참

(( integer1 >= integer2 ))    integer1이 integer2보다 크거나 같으면 참

# if (( $? != 0 )) ; then

# while ((n>0))

# if ((n<2) || !length(part[2])) ; then

# if ( $1 != mypid ) ; then

# if (( $1 > $2 )) ; then

3.Shell Programming

u        if 조건문

if 조건문

then

   명령어

[elif 조건문

then

   명령어]

[else

   명령어]

fi

if 조건문; then 명령어; [elif 조건문; then 명령어;] [else 명령어;] fi

:wq# vi if1.sh

X=hello

if [ $X = hello ]

then

   echo “Welcome”

else

   echo “Goodbye”

fi

:wq

# sh if1.sh

Welcome

# vi if2.sh

if [ -f temp ]

then

   mv temp temp1

elif [ -f temp1 ]

then

   mv temp1 temp2

fi

:wq

# sh if2.sh

u        case 조건문

case 변수 in

변수값1|변수값2…)

   명령어;;

변수값3|변수값4…)

   명령어;;

*)

   명령어;;

esac

#  vi case.sh

case $1 in

-d|-r)

        rmdir $dir1

        echo “directory removed” ;;

-o)

        echo “option -o” ;;

*)     

        echo “Invalid option,Try again…” ;;

esac

:wq

# chmod 777 case1.sh

# ./case.sh -o

option -o

u        while 반복문

while 조건문

do

   명령어

done

– 다음은 모두 같은 while문이다.

while [ 1 ]

do

  echo “Test”

done

while true

do

  echo “Test”

done

while [ : ]

do

  echo “Test”

done

while :

do

  echo “Test”

done

# vi while1.sh

count=$(who|grep -v root|wc -l)

while [ “$count” -gt 0 ]

do

   echo “Users still logged in…”

   sleep 1

   count=$(who|grep -v root|wc -l)

done

:wq

# sh while1.sh

# vi while2.sh

# /usr/bin/sh

#

print -n “Enter a value : “

read Value

print “Thank You”

count=0

while [ “$count” -lt “$Value” ]

do

   (( count=count + 1 ))

   print “Still sleeping for the $count th time…”

   sleep 2

done

print “End of $0”

:wq

# sh while2.sh

u        for 반복문

for 변수 [in 변수값1,변수값2,…]

do

   명령어

done

# vi for1.sh

for name in $(cut -d -f1 /etc/passwd)

do

   mailx $name < message.txt

   echo “Mail sent to $name”

done

:wq

# sh for1.sh

# vi for2.sh

if [[ ! -d “$1” ]]

then

   exit 1

fi

filename=$(ls $1)

for onefile in $filename

do

   if [[ -f ${1}/$onefile ]]

   then

      ll ${1}/$onefile

   elif [[ -d ${1}/$onefile ]]

   then

      ll -d ${1}/$onefile

   fi

done

:wq

# sh for2.sh /etc

u        until 반복문

until 조건문

do

   명령어

done

# vi until.sh

count=$(who|grep -v root|wc -l)

until [ “$count” -eq 0 ]

do

   echo “Users still logged in…”

   sleep 1

   count=$(who|grep -v root|wc -l)

done

:wq

# sh until.sh

u        select 반복문

select 변수 [in 변수값1,변수값2,…]

do

   명령어

done

– select문은 PS3 prompt를 사용한다. PS3 shell 변수의 기본값은 #? 이다.

– 변수는 변수값1,변수값2,… 등이 할당된다.

– 입력된 변수의 값의 숫자는 REPLY라는 shell변수에 저장된다.

– exit,return,break 등의 명령어로 반복문을 빠져나올수 있다.

– [in 변수값1,변수값2,…]가 없을경우에는 Positional Parameter를 사용한다.

# vi edit.sh         ### Edit the file ###

select menu in $(ls) “Exit” ; do

   case $menu in

     Exit) exit;;

     “”) echo “Invalid selection. Try again!”;;

     *) cp $menu $menu.bak; vi $menu ;;

   esac ; done

:wq

# vi color.sh

  select color in red blue green

  do

     echo “$color is an $color color”

     echo “$REPLY is a REPLY value”

  done

:wq

# sh color.sh

1)red

2)blue

3)green

#? 1

red is an red color

1 is a PEPLY value

#? 2

blue is an blue color

2 is a REPLY value

#? ^C

#

# vi select.sh

PS3=”Enter your choice =>”

select menu in “full backup”

                  “partial backup”

do

 case $menu in

 “full backup”)

  fbackup –0uf /dev/rmt/0m –i /stand

  echo “Full backup has begun”

  exit 0;;

 “Partial backup”)

fbackup –0uf /dev/rmt/0m -i /opt

echo “Partial Backup has begun”

return;;

 *) echo “$REPLY is an invalid

             option. Try again!”;;

 esac

done

:wq

# sh select.sh

# vi nest.sh

  #### Nested Select Command Example ###

#! /usr/bin/sh

PS3=”Main Choice by number=>”

select menu in “List Files” “Exit”

do

   case $menu in

   “List Files”)

      PS3=”Sub Choice by number=>”

      select ls_option in “Short” “Long” “Main”

      do

         case $ls_option in

          “Short”) lsf;;

           “Long”) ll;;

           “Main”)

               PS3=”Main Choice by number=>”  ## Restore Prompt

               break 1 ;;  ## exit inner loop

           “”) echo “$REPLY is an invalid option. Try again!”;;

         esac

      done ;;

   “Exit”) exit;;

   “”) echo “$REPLY is an invalid option. Try again!”;;

   esac

done

:wq

# sh nest.sh

u        Function(함수)

function 함수명

{

  shell script

}

함수명()

{

  shell script

}

– shell script안에 선언할수도 있고 밖에 선언할수도 있다.

– 함수명이나 argument로 called될수 있다.

– 같은 process를 반복적으로 사용할때 유리하며 debugging하기가 쉽다.

– typeset -xf name 으로 함수명을 export하여 global 함수로 선언할수 있다.

# vi func1.sh

function exef

{

   if [ -x $1 ]

   then

      echo “$1 is executable”

   fi

}

for file in `ls`

do

   exef $file

done

:wq

# sh func1.sh

# vi func2.sh

Uppercase()

{

   echo $* | tr “[a-z]””[A-Z”]”

}

print -n “Enter in a string:”

read string

upper_string=$(Uppercase $string)

echo “The uppercase string is: $upper_string”

:wq

# sh func2.sh

# vi func3.sh       : Recursive Fuction

bottom_up

{

   typeset SAVEPWD

   echo “\nDirectory being listed is: $PWD\n”

   lsf

   if [ “$PWD” != “/” ]

   then

      SAVEPWD=$PWD

      cd ..

      bottom_up

      cd $SAVEPWD

   else

      echo “That’s the end!”

   fi

}

:wq

# sh func3.sh

u        Array(배열)

– shell script에서 사용할수 있는 배열은 1차원배열이다.

– 배열요소(element)는 최대 512-1024까지 쓸수 있다.

– 배열요소는 [0]부터 [1023]까지 쓸수 있다.

– Array subscript인 [N]에서 N은 integer또는 integer expression을 쓸수 있다.

# X[0]=first

# X[1]=second

# X[2]=third

# echo ${X[1]}

second

# echo ${X}         : ${X}는 ${X[0]}과 같음

first

# echo ${X[*]}             : ‘*’나 ‘@’는 모든 요소를 가르킴

first second third

# echo ${#X[*]}

3

# i=3

# X[2*(i+1)]=10

# print ${X[8]

10

# set -A YY 100 200 300    : set -A는 변수를 배열로 선언한다.

# print ${YY[0]} ${YY[1]} ${YY[2]}

100 200 300

# set +A YY 150

# print ${YY[@]}

150 200 300

4.Shell Command

u        : 명령어

– ‘:’ 명령어는 아무것도 수행하지 않으며, 어떤 영향도 미치지 않는다. ‘0’값이 return됨.

# vi xx.sh

if [ -f /opt ]; then

   ls

else

   :            아무것도 수행하지 않는다.

fi

:wq

u        . 명령어

# . /etc/profile

– /etc/profile이라는 프로그램을 수행한다. 이는 sh나 ksh처럼 또하나의 shell을 fork하여

  프로그램을 수행하지 않으며 이 프로그램은 수행가능한 permission이 없어도 된다.

  즉 이 파일은 ‘x’ permission이 없어도 된다.

u        alias 명령어

alias [-x] [ name[=value] … ]

# alias                             : 현재 setting된 모든 alias를 display

# alias a=alias

# a x=lsf

# alias i=’

> echo Users logged in are:

> who|sort

> echo I am `whoami`’

# i                                  : alias문을 수행한다.

# unalias i                        : alias변수 i를 unsetting한다.

# unalias -a                       : shell command에서 typing한 모든

                                        alias를 해제한다.

# alias -x who=’who|sort’       : Korn shell에서 who를 export하여

                                        subshell에서도 사용가능하다.

u        break 명령어

break [n]

– for,while,until,select문과 같은 반복문에서 exit할 때 사용한다.

– n을 쓰면 n레벨만큼 loop를 exit한다.

# vi break.sh

for file in x y z none

do

   if [ -x $file ]; then

      echo $file

      break

   fi

done

:wq

u        command 명령어

command [arg …]

– argument를 command로서 취급한다.

# command lsf       : lsf를 command로 사용한다.

# command aaa       : aaa를 command로 사용한다.

u        continue 명령어

continue [n]

– for,while,until,select문과 같은 반복문에서 continue이하의 문을 수행하지 않고

다시 시작한다.

    – n을 쓰면 n번째 반복문을 다시 시작한다.

# vi con.sh

for file in x y z

do

   if [ -x $file ]; then

      continue

      echo “$file is executable”

   fi

   echo $file is not executable

done

:wq

u        echo 명령어

echo [arg …]

# echo ‘This is a’ $var ‘example.’

# echo “This is a $var example.”

# echo “Enter your user name: \c”

> read user

> echo ‘User is’ $user

echo 에서 Escape Character

\b     backspace

\c     continue line. new line을

       하지 않고 계속 붙여서 print한다

\f     form feed

\n     new line

\r     carriage return

\t     tab

\v     vertival tab

\\     backslash

u        eval 명령어

eval [arg …]

– argument를 input으로 받아서 명령어로 수행하며 argument는 command나 shell

  script가 될수 있다.

# cmd=’ps -ef > ps.out’

# eval $cmd

# eval “grep jones $file|set|echo $1 $2 $3”

u        exec 명령어

exec [arg …]

– 새로운 process나 subshell을 만들어서 argument를 수행하지 않고 현재 shell로

  명령어를 바로 수행한다.

# exec 3< file          file desciptor number 3으로 file을 open한다.

# ecec 2> /dev/null     표준에러를 /dev/null로 출력한다.

u        expr 명령어         # man expr 참조

expr expression {+,-,\*,/} expression

expr expression {=,\>,\>=,\<,\<=,!=} expression

expr string1 : string2

# a=15

# expr $a + 5

20

# count=`expr $count + 5`

# A=batman

# expr substr $A 1 3

bat

# expr index $A m

4

u        fc 명령어

fc [-r] [-e example] [first [last]]

fc –l [-nr] [first [last]]

fc –s [old=new] [first]

fc –e – [old=new] [command]

– fc command는 history file을 list하거나 history file에서 command를 edit할 수있다.

# fc –l            : history file의 내용을 display한다.

# fc –l 20 25

# fc –l 10

# fc –e vi 15 20

# fc –e –          : 방금 실행한 command를 다시 실행한다. # r 명령과 같다.

# fc –e – ls=cd  

u        let 명령어

let “expression”

(( expression ))

– let는 산술 표현을 가능하게 하며 long integer 계산을 한다.

Operator

Description

!

/  %

+  –

<  <=  >  >=

==  !=

=

unary minus

logical negation

곱하기,나누기,몫

더하기,빼기

비교

같다,같지 않다

변수 할당

# x=10

# y=2

# let x=x+2

# echo $x

12

# let “x=x/(y+1)”

# echo $x

4

# (( x=x+1 ))

# echo $x

5

# x=12

# let “x<10”

# echo $?

1

# (( x > 10 ))

# echo $?

0

# if (( x > 10 ))

>then echo x greater

>else echo x not greater

>fi

x greater

u        read 명령어

read [-r] name…        : POSIX Shell only

read [-prsu] [name]    : Korn Shell only

-r          라인연속으로 쓰인 라인끝의 \를 해석하지 않는다.

-un         file descriptor n 으로부터 input을 read한다.

# vi read.sh

  while read -r xx yy

  do

     printf “%s %s \n” “$yy” “$xx”

done < input_file

:wq

u        return 명령어

return [n]

– 함수의 실행을 마치고 calling shell script에게 exit status n을 return한다.

– n이 없으면 return status는 함수의 마지막 command의 값이다.

– return이 함수의 밖에서 수행되면 exit로서 실행된다.

# vi return.sh

  search()

  {

     if grep xxx “$1” > /dev/null 2>&1

     then return 1

     else return 2

     fi

  }

:wq

# sh return.sh filename

u      set 명령어

l         Positional Parameter값 setting

# set spring summer fall winter

# echo $3

fall

# echo $*

spring summer fall winter

l         Positional Parameter Sorting

# set third first second

# echo $1 $2 $3

third first second

# set –s               : 값을 lexical order로 sorting함

# echo $1 $2 $3

first second third

# set +s            : unsetting

option         option-name meaning

——————————————————————————–

set –a         allexport   모든 parameter가 자동으로 export됨. == set -o
allexport

set -C         noclobber   #date>XX시 >로 overwrite하지못하게 함. date>|XX로는
가능

set –e         errexit     shell command fail시 즉시 logout또는 shell을 exit함

set –f         noglob             # ls * 시wild card문자를 인식못함

set –h         trackall   

set –k         keyword    

set –m         monitor     Background jogs이 각각다른 process group에서 수행되고

                           작업이 끝나면 message를 report함

set –o                     set –o monitor와 같이 option-name에 붙여서 옵션을

                           setting함

set –s                     positional parameter를 sort함

set –t                     shell을 exit한후에 command를 수행함

set –u         nounset     substituting시 unset parameter를 error로 취급함

set –v         verbose     command를 display한후 command 수행

set –x         xtrace             command수행시 command와 argument까지 print함.

                           shell script의 debug mode로 사용함.

              

set                        현재 setting된 모든 shell variable을 list함

set –                      -x와 –v option을 turn off하고 flag에 대한 argument

                           검사를 하지 않음

set —                     옵션의 어떤 변화도 하지못하게 함. # set — -;echo $1

                                      file명으로 시작하는 file을 rm할 경우 # set — -;rm
–aaa

# set –o ignoreeof          : ignoreeof라는 옵션을 turn on

# set +o vi                : vi의 옵션을 turn off

# set –o noglob            : noglob옵션을 turn on 시키고 wild card인

                                    *,[],-,!,? 등을 shell이 해석하지 못하게함

# set –o noexec            : shell의 syntax error를 check하기위해 사용.

                             이 옵션은 interactive shell에서는 사용되지

                                    않으며 shell script에서만 수행됨.

                             noexec 옵션은 실제로 shell을 수행하지 않으면서

                                       shell의 syntax error만을 check하는
명령어다.

# vi set1.sh

  set –o noexec

  echo “This is test

  ls

  cp /aaa /bbb

:wq

# ksh set1.sh

set1.sh: syntax error at line 2 : ‘”‘ unmatched

# vi set2.sh

  set –x

  ls

  echo “The Test”

  set +x

  lsf

:wq

# sh set2.sh

u        shift 명령어

shift [n]

shift command는 positional parameter($1,$2,$3..)의 내용을 왼쪽순으로 move한다.

# vi shift1.sh

  yflag=0

  zopt=””

  for arg in “$@”

  do

     if [ “x$arg” = x-y ]

     then

        yflag=1

        shift

     else

       zopt=”$2″

       shift 2

     fi

  done

:wq

u        trap 명령어

trap [command] [signal]

– signal 값은 # kill –l또는 # man kill 명령어로 볼수 있음.

# trap “echo ‘Command Failed'” 2

                       : ^C(interupt)를 치면 echo 문장이 수행됨.

# trap              : trap 명령을 수행한후 옵션이 없이 trap명령을 수행하면 현재

                    setting된 모든 trap내용을 보여줌

# trap “” 1 2 3

                       : 1}HUP 2)INT 3)QUIT가 입력되도 무시하라.

# trap “echo logout” 0

                       : signal이 ‘0’ 이면 NULL signal로서

                         shell에서 exit할때 command가 수행된다.

u      typeset 명령어

typeset [-][+]옵션  변수명[=변수값]

option      meaning

—————————————————————————–

[-]         변수명의 속성을 setting

[+]         변수명의 속성을 turn off

-Ln         왼쪽의 공백을 제거하고 왼쪽에서 n숫자만큼 cut

-Rn         왼쪽에 공백을 채우고 오른쪽에서 n숫자만큼 cut

-Z          오른쪽으로 shift하고, 첫번째 문자가 숫자이고 –L옵션과 같이

            쓰지 않았으면 왼쪽에 숫자0을 채움

-i          변수명을 integer로 선언

-f          변수명이 아니라 함수명으로 변수를 선언

-l          모든 영문대문자를 소문자로 변환

-u          모든 소문자를 대문자로 변환

-r          변수를 read-only로 만듬,즉 변수를 상수로 만듬

-x          변수를 export함, 즉 변수를 전역변수로 만듬

—————————————————————————–

# typeset

현재 setting되어있는 변수의 data type을 보여줌

# typeset AA

AA변수를 string변수로 선언,또한 함수내에서 Local변수 즉 지역변수로 선언

하지만, shell에서 변수는 default로 string data type임

# DATA=”Today we had very HOT weather”

# typeset –u DATA

# echo $DATA

TODAY WE HAD VERY HOT WEATHER

# typeset +u DATA : DATA변수의 속성을 turn off 

# DATA=”as of the “${DATA}

# echo $DATA

as of the TODAY WE HAD VERY HOT WEATHER

# AAA=123456789

# typeset –L3 AAA

# echo $AAA

123

# typeset –LZ X=00005

# print $X

5

# typeset –i X        : 변수X를  integer로 선언 # integer X와 같음

# typeset –i2 X     : 변수X를 2진수로 선언

# typeset –i8 X     : 변수X를 8진수로 선언

# typeset –i10 X    : 변수X를 10진수로 선언

# typeset –i16 X    : 변수X를 16진수로 선언

# typeset -r Y=123  : 변수Y를 readonly변수로 선언 # readonly Y=123과 같음

# typeset -f        : 모든함수와 그 값을 display함

# typeset -xf       : export된 모든함수와 그 값을 display함

# typeset -xf XX    : 함수명 XX를 export하여 global function으로 선언함

u        ulimit 명령어

ulimit  [-f] [n]

– ulimit command는 child process나 subprocess에 의해 사용된는 resources를 제한한다.

# ulimit               : 현재 limit값을 보여준다

# ulimit –f 1000       : 현재process나 향후 process가 write할 수 있는

                          file size를 1000 block(1000*512 byte)으로 제한한다.

# ulimit –f unlimited : child process가 생성할 수 있는 size의 제한을 없앤다.

5.Regular Expression(정규 수식)

u        Pattern Matching과 Regular Expression의 비교 – # man 5 regexp참조

Pattern Matching

Regular Expression

– POSIX shell에서 사용

– file name생성과 case문에서 사용

– UNIX command와 Text Editor에서 사용

  (ed,vi,ex,sed,awk,expr,grep)

– file name을 match한다

– character string을 match한다

– file name을 substitute한다

– string을 search해서 substitute한다

– 사용되는 특수문자

  ?,  *,  [ – ],  !

– 사용되는 특수문자

  .,  [],  -,  ^,  $,  *

u        하나의 문자와 Match – .(dot)

A.          : AB,Ab,AA,A9등과 같이 A다음에오는 어느한문자와 match

…         : 연속된 3문자와 match

# man 5 regexp|col -b|expand > regexp.man

# grep ‘RE.’ regexp.man       : RE다음에오는 어느한문자와 Match되는 라인만 출력

u        문자의 시작과 Match – ^

^abc        : 첫문자가 abc로 시작되는 문자와 match. abc,abcabc,abcdef등과 match

^C          : 문자의 시작에서 C와 match

^C$         : 하나의 문자 C와 match

^.$         : 하나의 문자로만 구성된 문자와 match

^[ABC]      : 첫문자가 ABC로 시작되는 문자와 match

u        문자의 끝과 Match – $

abc$        : 끝문자가 abc로 끝나는 문자와 match. defgabc,cccabc,abc등과 match

^…$       : 3개의 문자로만 구성된 문자와 match

\.$         : 문자의 끝에서 마침표(.)과 match

\*$         : 문자의 끝에서 (*)와 match

u        문자 Match – []

[Tt]he      : The나 the라는 글자를 search

h[iau]t     : hit,hat,hut의 글자와 match

[ABC]       : A,B,C를 포함하는 문자와 match

u        범위를 포함하는 문자와 Match – [ – ]

[a-z]       : 소문자 a부터 z까지 어느문자와도 match

[0-9]        : 0-9까지 어떤 하나의 숫자와 match

[0-57]      : 0,1,2,3,4,5,7과 match

[a-c5-8X-Z] : a,b,c,5,6,7,8,X,Y,Z중 하나의 문자와 match

[0-3-]      : 0,1,2,3,-와 match

u        Complemented문자 Match – [^  ]

[^ ]        : 공백이 아닌 한문자와 match

[^0-9]      : 0-9까지 숫자가 아닌 하나의 모든문자와 match

[^a-zA-Z]   : 영문 알파벳이 아닌 문자나 숫자와 match

[012^]      : 0,1,2,^와 match

^[^a-z]$    : 소문자을 제외한 나머지 문자중 하나와 match

# man 5 regexp|col -b|expand > regexp.man

# grep ‘^$’ regexp.man|wc -l         : 공백라인수를 출력한다.

# TMOUNT=`/sbin/mount | grep ‘^/tmp(/| )’ | wc -l`

# grep -q -e “^/usr/bin$” -e “^/usr/bin:” -e “:/usr/bin:”\

         -e “:/usr/bin$” /etc/PATH

u        Null 또는 여러 같은문자와 Match – *,+,?

B*          : Null문자,B,BB,BBB…등과 match

AB*C        : AC,ABC,ABBC…등과 match

A+          : A,AA,AAA…등과 match

AB+C        : ABC,ABBC,ABBBC…등과 match

A?          : Null문자 또는 A와 match

AB?C        : AC,ABC와 match

[A-Z]+      : 하나이상의 대문자와 match

(AB)        : AB문자와 match

(AB)+C      : ABC,ABABC,ABABABC…등과 match

AB.*XYZ     : ABXYZ,ABCXYZ,ABCCCCXYZ…등과 match

u        특수문자 Match – \

\*          : 특수문자 *와 match

\$          : 특수문자 $와 match

\\          : 특수문자 \와 match

\\\\\.\*$   : 문자의 끝에서 \\.* 와 match

u        Subexpression – \( … \)

– \(…\)구문을 사용한다.

– subexpression과 match하는 문자를 recall하기위해 ‘\숫자’를 사용한다.

– ‘\숫자’ 는 1-9까지 쓸수있다.

– \1 은 1번째 subexpression,\2 는 2번째 subexpression을 나타낸다.

# who

root       console      Oct 23 13:01

root       ttyp1        Oct 27 12:45

root       pts/0        Oct 22 09:03

# who|sed ‘s/\([^ ][^ ]*\)[^A-Z][^A-Z]*\(.*\)/\2–>\1/’

Oct 23 13:01–>root

Oct 27 12:45–>root

Oct 22 09:03–>root

– 첫번째 /\([^ ][^ ]*\) 는 공백이 아닌 하나이상의 문자와 match하며 뒷부분의

  \1 의 값과 같다.즉, 여기서는 username root를 가르킨다.

– 두번째 \(.*\) 는 최초로 대문자로 시작되는 문자와 match하며 뒷부분의

  \2 의 값과 같다. 여기서는 Oct를 가르킨다.

6.Sed(Stream Editor)

u        sed 형식

sed [-n] command input_file…

sed [-n] [-e command]… [-f script_file]… [input_file…]

-n          화면에 display하지 않는다. 단  p명령어일경우는 화면에 display한다.

            -n옵션은 -e나 -f옵션중 하나와 같이 사용할수 있다.

-e command  command를 editing하며, input file이 없으면 표준입력이 사용된다.

-f script   input file에서 editing command의 script file을 수행한다.

– sed는 입력파일로부터 한라인씩 data를 read한다.

– sed는 default로 화면에 출력을 하며 input file을 modify하지 않는다.

# sed “s/UNIX/Unix/g” file1 > file2.new

# sed -e “s/Miss/Ms/g” -e “s/Mrs/Ms/g” file2

# sed -n “1,10p” file2

# cat script

1,10p

# sed -n -f script file2

u        s(substitute)

[address [,address]] s/string_old/string_new/[flag]

flag        meaning

g           global substitution(전라인을 모두바꾼다)

p           print line

w file      file로 write한다

# sed “s/[Cc]omputer/COMPUTER/g” file1

# sed -e “1,5s/abc/xyz/” -e ‘s/kbs/mbc/’ file1 > file2

# sed “/abcde/s/ab/AB/g” file1

# sed -e ‘s/abc/xyz/w file2’ file1

# sed “3s/the/xyz/g” file1

# sed ‘3s/^the /xyz/’ file1

# sed -e “/the/s/ for /xyz/g

# cat file1| sed “/the/s/ for /xyz/gw file2

# sed “1,8s/aaa/bbb/g” file1 > file2

# sed “/^5/,/^15/s/from/FROM/g”

# sed -e “/^The first time/,/^End of file/s/lsf/ll/g”

# sed “1,$s/\/usr\/bin/\/sbin\/bin/g”

u        d(delete)

# sed “1,10d” fileA

   – fileA에서 1-10라인까지 delete한다.

# sed “/^From/!d” mbox

   – mbox file에서 From으로 시작되는 라인만 제외하고 모두 delete한다.

u        p(print),l(list),=,q(quit),r(read),w(write)

p           standard output에 print한다. -n옵션과 함께써도 print된다.

l           nonprinting문자도 같이 표준출력한다.

=           address 라인의 라인번호를 표준출력한다.

q           현재라인을 출력하고 sed를 종료한다.

r file      file의 내용을 read하여 표준출력한다.

w file      file에 address라인을 write또는 append한다.

# vi cap

   One potato, teo potato,

   three potato, four.

   Five potato, six potato,

   seven potato, more.

:wq

# sed -n “1,2p” cap

One potato, two potato,

three potato, four.

# sed -e “q” cap

One potato, teo potato,

# sed -e “/\./=” -e ” /[A-Z]/w file1″ cap

One potato, teo potato,

2

three potato, four.

Five potato, six potato,

4

seven potato, more.

# killproc() {

      for x in “$@”

      do

         pid=`ps -e |grep “$x” |sed -e ‘s/^  *//’ -e ‘s/ .*//’`

         [ ! –z “$pid” ] && echo killing $x && kill $pid
&

      done

  }

# findproc() {

    pid=`ps –e |grep “$1” |sed -e ‘s/^  *//’ -e ‘s/ .*//’`

    echo $pid

  }

# killproc() {           

      echo stopping $1

      pid=`/usr/bin/ps -e |

            /usr/bin/grep “$1” |

            /usr/bin/sed -e ‘s/^  *//’ -e ‘s/ .*//’`

            [ “$pid” != “” ] && kill $pid

  }

# if [ “$RWHOD” –ne 1 ]; then

      rval=2

  else

      pid=`ps -el | awk ‘( ($NF ~ /rwhod/) && ($4 != mypid)
&&

           ($5 != mypid)) { print $4 }’ mypid=$$ `

      if [ “X$pid” != “X” ]; then

         if kill $pid; then

            echo “rwhod stopped”

         else

            rval=1

            echo “Unable to stop rwhod”

         fi

      fi

  fi

#

#

#

# ARRAYMON_PID=`ps -ef | awk ‘$0 ~ /.*arraymon*/ && $0 !~
/.*awk.*/

                  { print $2 }’`

  if [ “$ARRAYMON_PID” ]

  then

     echo “Killing disk array monitor daemon.”

     kill -9 $ARRAYMON_PID

     sleep 2

     ARRAYMON_PID=`ps -ef | awk ‘$0 ~ /.*arraymon*/ && $0 !~
/.*awk.*/

                     { print $2 }’`

     if [ “$ARRAYMON_PID” ]

     then

       echo “ERROR:  Could not kill ${ARRAY_MONITOR_DAEMON}”

     fi

  fi

#

7.Shell Program 예제

-shell script를 위한 data file은 다음과 같다.

# vi data

  100 200 300 400

  500 600 700 800

  900 1000 1100 1200

  1300 1400 1500 1600

  1200 800 400 0

:wq

# vi exp1.sh

if [[ ! -f “$1” ]]

then

   echo “${0##*/}”

   exit 1

else

   filename=$1

fi

exec 3< $filename : file descriptor 3으로 filename를 open

typeset -i II=0   : XX를 integer로 선언

while read -u3 AA[0] AA[[1] AA[2] AA[3]

do

   for II in 0 1 2 3

   do

      (( total[II]=${total[II]} + ${AA[II]} ))

   done

print “Subtotal : “

print ${total[*]}

done

print “Total for the four columns are : “

print ${total[@]}

:wq

# sh exp1.sh

#!/usr/bin/sh

######################## /etc/profile ##########################  

trap “” 1 2 3                   

PATH=/usr/bin:/usr/ccs/bin:/usr/contrib/bin

MANPATH=/usr/share/man:/usr/contrib/man:/usr/local/man

if [ ! -d /usr/sbin ]

then

   PATH=$PATH:/sbin

else

   if [ -r /etc/PATH ]

   then

      grep -q -e “^/usr/bin$” -e “^/usr/bin:” -e “:/usr/bin:”\

                -e “:/usr/bin$” /etc/PATH

      if [ $? -eq 0 ]

      then

         PATH=`cat /etc/PATH`

      else

         PATH=$PATH:`cat /etc/PATH`

      fi

   fi

fi

export PATH

if [ -r /etc/MANPATH ]

then

   MANPATH=`cat /etc/MANPATH`

fi

export MANPATH

if [ -r /etc/TIMEZONE ]

then

   . /etc/TIMEZONE 

else

   TZ=MST7MDT       

   export TZ

fi

if [ ! “$VUE” ]; then

   if [ “$TERM” = “” -o “$TERM” = “unknown” -o “$TERM” = “dialup”  \

                         -o “$TERM” = “network” ]

   then

      eval `ttytype -s -a`

   fi

   export TERM

   if [ “$ERASE” = “” ]

   then

      ERASE=”^H”

      export ERASE

   fi

   stty erase $ERASE

   trap “echo logout” 0

   cat /etc/copyright

   if [ -r /etc/motd ]

   then

      cat /etc/motd

   fi

   if [ -f /usr/bin/mail ]

   then

      if mail –e

      then echo “You have mail.”

      fi

   fi

   if [ -f /usr/bin/news ]

   then news –n

   fi

   if [ -r /tmp/changetape ]

   then

      echo “\007\nYou are the first to log in since backup:”

      echo “Please change the backup tape.\n”

      rm -f /tmp/changetape

   fi

fi

trap 1 2 3

###################### The End ##########################

#!/usr/bin/sh

############# /.profile ################  

set +u

PATH=/usr/sbin:$PATH:/sbin:/home/root

if [ ! “$VUE” ]; then

   if [ “$TERM” = “” ]

   then

      eval ` tset -s -Q -m ‘:?hp’ `

   else

      eval ` tset -s -Q `

   fi

   stty erase “^H” kill “^U” intr “^C” eof “^D” susp “^Z”

   stty hupcl ixon ixoff

   tabs

   echo

   echo “Value of TERM has been set to \”$TERM\”. “

   export TERM

   EDITOR=vi

   export EDITOR

fi

set –u

trap “echo ‘logout root'” 0

MAIL=/var/mail/root

echo “WARNING:  YOU ARE SUPERUSER !!\n”

export PS1=`hostname`’:$PWD# ‘

############################# The End ##############################

#!/sbin/sh

######################## /sbin/init.d/inetd #######################

PATH=/sbin:/usr/sbin:/usr/bin

export PATH

rval=0

set_return() {

        x=$?

        if [ $x -ne 0 ]; then

                echo “EXIT CODE: $x”

                rval=1  # always 1 so that 2 can be used for other
reasons

        fi

}

case “$1” in

start_msg)

   echo “Start Internet services  daemon” ;;

stop_msg)

   echo “Stopping Internet services daemon” ;;

‘start’)

   if [ -f /etc/rc.config ]; then

      . /etc/rc.config

   else

      echo “ERROR: /etc/rc.config defaults file MISSING”

   fi

   mask=`umask`

   umask 000

   [ -x /usr/sbin/inetd ] && /usr/sbin/inetd $INETD_ARGS

   if [ $? -eq 0 ]; then

      echo “Internet Services started”

   else

      echo “Unable to start Internet Services”

   fi

   umask $mask

   ;;

‘stop’)

   if [ -f /etc/rc.config ]; then

      . /etc/rc.config

   else

      echo “ERROR: /etc/rc.config defaults file MISSING”

   fi

   /usr/sbin/inetd -k

   set_return

   if [ $rval -eq 0 ]; then

      echo “Internet Services stopped”

   else

      echo “Unable to stop Internet Services”

   fi

   ;;

*)

   echo “usage: $0 {start|stop}”

   rval=1

   ;;

esac

exit $rval

############################ The End ##############################3

#!/sbin/sh

############# /sbin/rc ################      

arg=$1

arg2=$2

PATH=/sbin

export PATH

/sbin/stty clocal icanon echo opost onlcr ixon icrnl ignpar 2>
/dev/null

umask 022

get_scripts() {

   state=$1

   mode=$2

   dir=/sbin/rc${state}.d

   ls $dir 2>/dev/null |

   while read name

   do

      case $name in

      ${mode}*)

         path=$dir/$name

         if [ “$mode” = “S” ]; then

            desc=`$path start_msg`

         elif [ “$mode” = “K” ]; then

            desc=`$path stop_msg`

         fi

         echo $path $desc

     esac

  done

}

if [ -f /sbin/rc.utils ]; then

   . /sbin/rc.utils

else

   init_list()

   {

      echo $1

   }

   add_list()

   {

      eval $1

   }

   run_list()

   {

      :

   }

fi

# If /etc/rc.config contains default information (first boot),

# /sbin/auto_parms will invoke /sbin/set_parms to remedy the situation.

# For 10.0 release, the default HOSTNAME is unset or an empty string.

# Assume a timezone if /etc/TIMEZONE does not exist.

TZ=EST5EDT

if [ -f /etc/rc.config ]; then

   . /etc/rc.config

   if [ -x /sbin/auto_parms ]; then

      /sbin/auto_parms

   else

      echo “\nWARNING: /sbin/auto_parms does not exist”

      echo “DHCP invocation skipped.”

   fi

else

   echo “\nWARNING: /etc/rc.config does not exist”

   echo “System name not set, default $TZ assumed.”

fi

export TZ

# Set runlevel information

set `who -r` x

new=$7         # new run level

old=$9         # previous run level

# Check to see if we are run from /etc/inittab, or from the command line.

# If run from the command line, set the old run-level to the new
run-level.

if [ $PPID != 1 ]; then

   old=$new

   # If the new run-level was specified on the command line,go to that
state

   # instead.

   if [[ -n $arg2 ]]; then

      new=$arg2

   fi

fi

if [ “$new” = S ]; then

   new=0

   tosingle=1

else

   tosingle=0

fi

BOOT=0

if [ “$old” = S ]; then

   old=0

   BOOT=1

fi

# Process scripts

found=0

if [ “$new” -gt “$old” ]; then

   # new run level is higher than old, so run start scripts in

   # all intermediate run levels and in new run level.

   if [ $BOOT = 1 ]; then

      init_list “HP-UX Start-up in progress”

   else

      init_list “Transition to run-level $new in progress”

   fi

   typeset -i lvl=$old

   lvl=lvl+1

   while [ $lvl -le “$new” ]; do

      get_scripts $lvl S |

      while read name descrip; do

         if [ -s “$name” ]; then

            add_list “$name start” “$descrip”

            found=1

         fi

      done

      lvl=lvl+1

   done

elif [ “$new” -lt “$old” ]; then

   # new run level is lower than old level, so run kill scripts

   # in all intermediate levels and in new level.

   if [ “$new” = 0 ]; then

      init_list “System shutdown in progress”

   else

      init_list “Transition to run-level $new in progress”

   fi

   typeset -i lvl=$old

   lvl=lvl-1

   while [ $lvl -ge “$new” ]; do

      get_scripts $lvl K |

      while read name descrip; do

         if [ -s “$name” ]; then

            add_list “$name stop” “$descrip”

            found=1

         fi

      done

      lvl=lvl-1

   done

   # If we’re ending up in state 0 or S, run the start scripts for

   # that state.

   if [ “$new” = 0 ]; then

      get_scripts 0 S |

      while read name descrip; do

         if [ -s “$name” ]; then

            add_list “$name start” “$descrip”

            found=1

         fi

      done

   fi

else

   # old and new run levels are the same.  Assume that execution

   # is from the command line and run start scripts for the current

   # run level

   init_list “Starting subsystems for run-level $new”

   get_scripts ${new} S |

   while read name descrip; do

      if [ -s “$name” ]; then

         add_list “$name start” “$descrip”

         found=1

      fi

   done

fi

if [ $found = 1 ]; then

   if [ “$BOOT” = 1 ]; then

      run_list boot

   else

      run_list

   fi

fi

if [ “$new” = 0 ]; then

   case $arg in

   “shutdown”)

      exec /sbin/sh

      ;;

   “reboot”)

      /sbin/reboot

      ;;

   “off”)

      /sbin/reboot -h

      ;;

   esac

   #If transitioned to real state 0 (that is, not state S) via init,
halt.

   if [[ $PPID -eq 1 && “$tosingle” -ne 1 ]]; then

      /sbin/reboot -h

   fi

fi

# Output message to indicate completion

echo

if [ $BOOT = 1 ]; then

   echo “The system is ready.”

else

   echo “Transition to run-level $new is complete.”

fi

############################## The End #################################3

#!/sbin/sh

##################### /sbin/init.d/net ##########################

#

# net:  configure lan interface(s) at initialization time.

# /etc/rc.config.d/netconf defines the configuration parameters:

#

# INTERFACE_NAME[i]:      network interface name (e.g., lan0)

# IP_ADDRESS[i]:          IP address of your system in decimal dot format

# SUBNET_NETMASK[i]:     subnetwork mask in decimal dot format

# BROADCAST_ADDRESS[i]:  broadcast address (other than default) in
decimal

#                             format

# LANCONFIG_ARGS[i]:      lanconfig(1m) options (e.g., ieee, ether)

# LOOPBACK_ADDRESS:       loopback address (always 127.0.0.1)

#

# ROUTE_DESTINATION[i]:  route destination

# ROUTE_MASK[i]:       subnet mask

# ROUTE_GATEWAY[i]:       local or remote IP address of gateway

# ROUTE_COUNT[i]:         zero for local gateway, one for remote gateway

# ROUTE_ARGS[i]:          route command options and arguments

#

###########################################################################

set +u  

export PATH=/sbin:/usr/sbin:$PATH

NETCONF=/etc/rc.config.d/netconf

NETSTAT_DATA=/var/adm/netstat_data

OKAY=0

ERROR=1

WARNING=2

# $1 = name of array

# return highest array element index in env; return -1 if no elements

function maxindex {

   # find only lines that start with “var[…]=”, grab only the number

   # between “[…]”, and print only the last one.

   # we would like to use `sed` as follows:

   #    typeset i=$(set | sed -n ‘s/^’$1’\[\([[:digit:]]\{1,\}\)\]=.*$/\1/p’

   #                | tail -1)

   # but it is not guaranteed to be in a mounted file system at this
time.

   typeset line

   typeset i=-1

   set | while read line; do

      # strip “var[” and “]=…”, leaving only number between “[…]”

      line=${line#*$1\[}

      line=${line%%\]=*}

      # if line is all digits, we found “var[…]=…”,

      # and line is string between “[…]”

      if [[ -n $line && -z ${line##*([[:digit:]])} ]]; then

         i=$line

      fi

   done

   print — $i

   return 0

}

##########

#  main   #

##########

case $1 in

start_msg)

   print “Configure LAN interfaces”

   exit $OKAY

   ;;

stop_msg)

   print “Unconfigure LAN interfaces”

   exit $OKAY

   ;;

stop)

   exit $OKAY

   ;;

start)

   ;;  # fall through

*)

   print “USAGE: $0 {start_msg | stop_msg | start | stop}” >&2

   exit $ERROR

   ;;

esac

###########

#  start  #

###########

# Remove the existing /var/adm/netstat_data file.  The first time

# netstat is executed, a new /var/adm/netstat_data file will be

# created.

rm -f $NETSTAT_DATA

# Get actual configuration

if [[ -f $NETCONF ]]; then

   . $NETCONF               # display any errors

   if (($? != 0)); then

      # NB: this is not working as expected:  status is not propagated!

      print “ERROR:   Incorrect data in the file $NETCONF.” >&2

      exit $ERROR

   fi

else

   print “ERROR:   Missing the file $NETCONF.” >&2

   exit $ERROR

fi

rval=$OKAY

# Do ifconfig and lanconfig commands for each interface

# `foo=$(print $foo)` collapses whitespace, remove surrounding whitespace

# We can have __fewer__ IP_ADDRESSes than INTERFACE_NAMEs (interfaces to
be

# ignore).  We can also have __fewer__ SUBNET_MASKs, BROADCAST_ADDRESSes
and

# LANCONFIG_ARGS (defaulted).  But we cannot have __more__.

# sanity check

nIF=$(maxindex INTERFACE_NAME)

if (($(maxindex IP_ADDRESS) > nIF)) || \

   (($(maxindex SUBNET_MASK) > nIF)) || \

   (($(maxindex BROADCAST_ADDRESS) > nIF)) || \

   (($(maxindex LANCONFIG_ARGS) > nIF))

then

   print “WARNING: Missing INTERFACE_NAME for corresponding IP_ADDRESS,
SUBNET_MASK,” >&2

   print ”         BROADCAST_ADDRESS or LANCONFIG_ARGS in the file”
>&2

   print ”         $NETCONF.  Excess variables will be ignored.”
>&2

   rval=$WARNING

fi

i=0

while ((i <= nIF)); do

   NAME=$(print ${INTERFACE_NAME[i]})

   INTERFACE_NAME[i]=$NAME          # without whitespace for route tests
below

   IP=$(print ${IP_ADDRESS[i]})

   IP_ADDRESS[i]=$IP                 # without whitespace for route tests
below

   if [[ $IP = “RARP” ]]; then

      IP=`/usr/sbin/rarpc $NAME`

      IP_ADDRESS[i]=$IP              # without whitespace for route tests
below

   fi

   if [[ -n $NAME && -n $IP ]]; then

      MASK=$(print ${SUBNET_MASK[i]})

      [[ -n “$MASK” ]] && MASK=”netmask $MASK”

      BCAST=$(print ${BROADCAST_ADDRESS[i]})

      [[ -n “$BCAST” ]] && BCAST=”broadcast $BCAST”

      PROTO=$(print ${LANCONFIG_ARGS[i]})    # do not set PROTO to any
default

      emsg=$(ifconfig $NAME $IP $MASK $BCAST up 2>&1)

      status=$?

      if ((status == 0)) && [[ -n $PROTO ]] ; then

         emsg=$(lanconfig $NAME $PROTO 2>&1)

         status=$?

      fi

      if ((status != 0)); then

         print “ERROR:   $NAME interface: $emsg” >&2

         rval=$ERROR

      fi

   fi

   let i=i+1

done

IP=$(print $LOOPBACK_ADDRESS)

if [[ -n $IP ]]; then

   emsg=$(ifconfig lo0 $IP up 2>&1)

   if (($? != 0)); then

      print “ERROR:   lo0 interface: $emsg” >&2

      rval=$ERROR

   fi

else

   print “ERROR:   Missing LOOPBACK_ADDRESS in the file $NETCONF.”
>&2

   print ”         lo0 interface not initialized.” >&2

   rval=$ERROR

fi

# Do route command for each configured route

# Note:  ${IP_ADDRESS[i]} must have whitespace removed already (above)

# We must have the __same__ number of ROUTE_GATEWAYs as
ROUTE_DESTINATIONs.

# But we can have __fewer__ ROUTE_COUNTs and ROUTE_MASKs (defaulted).

n=$(maxindex ROUTE_DESTINATION)

if (($(maxindex ROUTE_GATEWAY) != n)) || \

   (($(maxindex ROUTE_COUNT) > n))

then

   print \

      “WARNING: Missing ROUTE_DESTINATION for corresponding ROUTE_GATEWAY”
>&2

   print ”         or ROUTE_COUNT in the file $NETCONF.” >&2

   print ”         Excess variables will be ignored.” >&2

   rval=$WARNING

fi

i=0

while ((i <= n))

do

   DEST=$(print ${ROUTE_DESTINATION[i]})

   GWAY=$(print ${ROUTE_GATEWAY[i]})

   if [[ -n $DEST && -n $GWAY ]]; then

      COUNT=$(print ${ROUTE_COUNT[i]})

      if [[ -z $COUNT ]]; then

         # default COUNT:  if GWAY is one of the local interface IP

         # addresses, count is 0; otherwise, count is 1.

         COUNT=1

         k=0

         while ((k <= nIF)); do

            if [[ $GWAY = ${IP_ADDRESS[k]} && -n ${INTERFACE_NAME[k]}
]]; then

               COUNT=0

               break;

            fi

            let k=k+1

         done

      fi

      ARGS=${ROUTE_ARGS[i]}

      MASK=$(print ${ROUTE_MASK[i]})

      if [[ -z $MASK ]]; then

          # No subnet mask

          if [[ -z $ARGS ]]; then

             # No arguments

             emsg=$(route add $DEST $GWAY $COUNT 2>&1)

          else

             # With arguments

             emsg=$(route $ARGS add $DEST $GWAY $COUNT 2>&1)

          fi

      else

         # Subnet mask has been entered.

         if [[ -z $ARGS ]]; then

            # No arguments

            emsg=$(route add $DEST netmask $MASK $GWAY $COUNT
2>&1)

         else

            # With arguments

            emsg=$(route $ARGS add $DEST netmask $MASK $GWAY $COUNT
2>&1)

         fi

      fi

      # ignore “entry in use” errors.  these can arise because we

      # booted via NFS diskless, which added routes already

      if (($? != 0)) && [[ -n ${emsg##*entry in use*} ]]; then

         print “ERROR:   $emsg” >&2

         rval=$ERROR

      fi

   fi

   let i=i+1

done

# add loopback route for local interfaces to improve performance

k=0

while ((k <= nIF))

do

   if [[ -n ${IP_ADDRESS[k]} && -n ${INTERFACE_NAME[k]} ]]; then

      emsg=$(route add ${IP_ADDRESS[k]} $LOOPBACK_ADDRESS 0 2>&1)

      if (($? != 0)) && [[ -n ${emsg##*entry in use*} ]]; then

         print “ERROR:   $emsg” >&2

         rval=$ERROR

      fi

   fi

   let k=k+1

done

exit $rval

##################### The End  ###########################

Leave a Reply

Your email address will not be published. Required fields are marked *