본문 바로가기
Common Tech.

SHELL Programming

by 레이루이 2008. 5. 7.
반응형


한국 휴렛팩커드 소프트웨어 지원사업부

 

ASE 

 

 

 

 

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  ###########################

 

 

 

 

반응형