2008年7月31日 星期四

Shell script Examples

Shell script Examples

轉貼自此


SH 教學
1. 一個簡單的例子

#!/bin/sh
echo "** Non-root UID=0 or GID=0 accounts:"
grep ':00*:' /etc/passwd | \
  awk -F: 'BEGIN        {n=0}
           $1 != "root" {print $0 ; n=1}
           END          {if (n==0) print "None found."}'


---------------------------------------------------------------------
2. shift 的用法,及一些特殊符號的意義

#!/bin/sh
echo $1 $2 $3
echo $#
# will be 4
shift
echo $1 $2 $3
echo $#
# will be 3
#  "$*" = "$1 $2 $3....$n"
echo $*
#  "$@" = "$1" "$2" "$3" "$4" ..."$n"
echo $@
#
# $?  Exit status of previous command
# $$  PID of this shell's process
# $!  PID of the most recently started backgroup job
echo $?
echo $$
echo $!


---------------------------------------------------------------------
3. 變數設定的方法,及特殊設定

#!/bin/sh
item=aaaa
item1=bbbb
echo ${item}1 $item1
#!/bin/sh
name=rache1
echo ${name-tatiana}
# show rache1

echo ${name2-tatiana}
# show tatiana

echo ${name=tatiana}
# show rache1

echo ${name2=tatiana}; echo $name2
# show tatiana
#      tatiana

dir=${name5-`pwd`}; echo $dir


---------------------------------------------------------------------
4. if 的用法,有很多比較方法 -s, -r, -f, -d .. 請看 man if or man test
   例如:底下兩敘述是相同的
   if test -z "$var"; then ...
   if [ -z "$var" ]; then ...

#!/bin/sh
# in sh , echo -n 只有當 /usr/ucb 路徑在 /usr/bin 之前才有用

if [ -f /usr/bin/ls ]; then
  echo -n " ls command found "
fi

#!/bin/sh
strings /vmunix | grep UNIX > /tmp/motd
head -1 /etc/motd | grep UNIX > /tmp/th
if [ -z /tmp/th ]
then
  cat /etc/motd >> /tmp/motd
else
  tail +2 /etc/motd >> /tmp/motd
fi
mv /tmp/motd /etc/motd


---------------------------------------------------------------------
5. 再看一個加上變化的 if

#!/bin/sh
set `who -r`
if [ $9 = "S" ]; then
  echo "The system is coming up. Be patient."
elif [ $7 = "2" ]; then
  echo "Changing to state 2."
else
  echo "Changing to state 3."
fi

底下是更多的 if 的例子
if [ $9 = "S" ]
if [ -s /etc/ptmp ]
if [$# -lt 4 ]
if [ ! -f /etc/.fscksk ]
if [ $? -eq 0 ]
if [ $? -ne 0 ]
if test -z "$var"
if [ -z "$var" ]

---------------------------------------------------------------------
6. 還是 if 的例子

#!/bin/sh
pid=`/bin/ps -e | grep 'lpsched$' | sed -e 's/^  *//' -e 's/ .*//'`
echo ${pid}
if [ "${pid}" != "" ]
then
  echo $pid
  /bin/kill ${pid}
fi

if [ -r /fastboot ]; then
  echo "skip the fsck"
else
  echo "do the fsck"
fi

if [ -d /etc/rc0.d ]
then
  echo "run the K files"
fi

if [ -x /etc/inetd ]
then
  echo "inetd"
fi

if [ "${BOOT}" = "yes" -a -d /etc/rc0.d ]
then
  echo "run /etc/rc0.d"
fi  



---------------------------------------------------------------------
7. while 的語法,與讀進參數

#!/bin/sh
cat /etc/vfstab |
while read DEVICE MOUNT_DIR READONLY FS DUMMY1 DUMMY2
do
  echo "$DEVICE, $MOUNT_DIR, $READONLY, $FS, $DUMMY1, $DUMMY2"
done


---------------------------------------------------------------------
8. case 的用法,和 csh 真的差很多
   $? 是執行命令後的 return status , 0: succeed , 1: false

#!/bin/sh
#/etc/fsck -p > /dev/console
ls / > /dev/null
case $? in
  0)
    echo "return 0"
    ;;
  2)
    exit 1
    ;;
  4)
    echo "return 4"
    ;;
  *)
    echo "Unknown error in reboot" > /dev/console
    exit 1
    ;;
esac
  
---------------------------------------------------------------------
9. 再一個 case 的範例

# can get the same result when "$1" or $1
#case $1 in
case "$1" in
   'start')
           echo "start"
           ;;
   'stop')
           echo "stop"
           ;;
   '-abc')
           echo "-abc option"
           ;;
   '-h'|'-help')
           echo "help option"
           ;;
   *)
           echo "usage: $0 {start|stop}"
           ;;
esac

echo "--------------------------------------------"

shell=tcsh
case $shell in
  *csh)
     echo "C-shell style shells are not acceptable"
     ;;
  *zsh)
     echo " zsh is not acceptable"
     ;;
esac


---------------------------------------------------------------------
10. 一個 for 的簡單例子

#!/bin/sh
for d in /tmp /usr/tmp /tmp/tmp ; do
  echo $d
done


---------------------------------------------------------------------
11. 同樣的 for , 以 *.sh 代替

for file in *.sh ; do
  wc -l $file
done


---------------------------------------------------------------------
12. 取得使用者回答的範例

echo "fsck all disks? [y] \c"
read ans
#echo $ans
if [ $ans = 'y' -o $ans = 'Y' ] ; then
  echo "Yes"
else
  echo "no.."
fi


---------------------------------------------------------------------
13. 迴圈 while ,這個例子會印出 1 2 3 4 5

#!/bin/sh
i=1
while [ $i -le 5 ]; do
  echo -n $i
  i=`expr $i + 1`
done

---------------------------------------------------------------------
14. 一個字串連結的例子 $a$b$c = cmd , 又 cmd = date

#!/bin/sh
a=c; b=m; c=d; cmd=date
eval $`echo $a$b$c`

---------------------------------------------------------------------
15. 這個例子會列出目前目錄下的子目錄名稱

#!/bin/sh
# usage: process sub-directory
dir=`pwd`
for i in *; do
  if [ -d $dir/$i ]
  #if test -d $dir/$i

  then
    cd $dir/$i
#    while (echo -n "$i: (waiting command") ; read x; do
#      eval $x
#    done
    echo $i
    cd ..
  fi
done

---------------------------------------------------------------------
16. 更改檔名  *.html -> *.htm

#!/bin/sh
for i in *.html ; do
  echo $i
  mv $i `basename $i .html`.htm
done

----------------------------------------------------------------------
17. 更改檔名 *.htm -> *.html

#!/bin/sh
for i in *.htm ; do
  echo $i
  mv $i `basename $i .htm`.html
done

----------------------------------------------------------------------
18. 一個抓下來的片段

  while [ $# != 0 ]
  do
    case $1 in
     -v) doversion=1;;
     -B) BASEDIR=$2; shift;;
     -l) LOGDIR=$2; shift;;
     -w) WORKDIR=$2; shift;;
     -B) BINDIR=$2; shift;;
     -c) RCFILE=$2; shift;;
     -e) EXPLAINREPORT=I;;
     -E) EXPLAINREPORT=Y;;
     -S) SERVERCHECK=Y;;
     -O) OS=$2; shift;;
     -A) ARCH=$2; shift;;
     -R) REV=$2; shift;;
     -t) Tiger_TESTMODE=Y;;
      *) echo "--ERROR-- [con006e] Unknown option $1";;
    esac
    shift;
  done

----------------------------------------------------------------------
19. 一個實際設定 Solaris 2.x Ftp server 的 shell script

#!/bin/sh
# script to setup SunOS 5.3 anonymous ftp area
#
#set OS_VERSION = `uname -r`
# handle the optional command line argument
case $# in

  # the default location for the anon ftp comes from the passwd file
  0) ftphome="`grep '^ftp:' /etc/passwd | cut -d: -f6`"
     ;;

  1) if [ "$1" = "start" ]; then
        ftphome="`grep '^ftp:' /etc/passwd | cut -d: -f6`"
     else
        ftphome=$1
     fi
     ;;

  *) echo "Usage: $0 [anon-ftp-root]"
     exit 1
     ;;
esac

if [ -z "${ftphome}" ]; then
   echo "$0: ftphome must be non-null"
   exit 2
fi

# This script assumes that ftphome is neither / nor /usr so ...
if [ "${ftphome}" = "/" -o "${ftphome}" = "/usr" ]; then
   echo "$0: ftphome must not be / or /usr"
   exit 2
fi

# If ftphome does not exist but parent does, create ftphome
if [ ! -d ${ftphome} ]; then
    # lack of -p below is intentional
    mkdir ${ftphome}
fi

echo Setting up anonymous ftp area ${ftphome} for SunOS `uname -r`
#echo Setting up anonymous ftp area ${ftphome} for SunOS $OS_VERSION

# Ensure that the /usr/bin directory exists
if [ ! -d ${ftphome}/usr/bin ]; then
   mkdir -p ${ftphome}/usr/bin
fi

cp /usr/bin/ls ${ftphome}/usr/bin

chmod 111 ${ftphome}/usr/bin/ls

# Now set the ownership and modes to match the man page
chown root ${ftphome}/usr/bin
chmod 555 ${ftphome}/usr/bin

# this may not be the right thing to do
# but we need the bin -> usr/bin link
if [ -r ${ftphome}/bin ]; then
   mv -f ${ftphome}/bin ${ftphome}/Obin
fi
ln -s usr/bin ${ftphome}

# Ensure that the /usr/lib and /etc directories exist
if [ ! -d ${ftphome}/usr/lib ]; then
   mkdir -p ${ftphome}/usr/lib
fi
if [ ! -d ${ftphome}/etc ]; then
   mkdir -p ${ftphome}/etc
fi

#Most of the following are needed for basic operation, except
#for libnsl.so, nss_nis.so, libsocket.so, and straddr.so which are
#needed to resolve NIS names.

cp /usr/lib/ld.so /usr/lib/ld.so.1 ${ftphome}/usr/lib

for lib in libc libdl libintl libw libnsl libsocket \
    nss_nis nss_nisplus nss_dns nss_files
do
    cp /usr/lib/${lib}.so.1 ${ftphome}/usr/lib
    rm -f ${ftphome}/usr/lib/${lib}.so
    ln -s ./${lib}.so.1 ${ftphome}/usr/lib/${lib}.so
done

cp /usr/lib/straddr.so.2 ${ftphome}/usr/lib
rm -f ${ftphome}/usr/lib/straddr.so
ln -s ./straddr.so.2 ${ftphome}/usr/lib/straddr.so

cp /etc/passwd /etc/group /etc/netconfig ${ftphome}/etc

chmod 555 ${ftphome}/usr/lib/*
chmod 444 ${ftphome}/etc/*

# Now set the ownership and modes
chown root ${ftphome}/usr/lib ${ftphome}/etc
chmod 555 ${ftphome}/usr/lib ${ftphome}/etc

# Ensure that the /dev directory exists
if [ ! -d ${ftphome}/dev ]; then
   mkdir -p ${ftphome}/dev
fi

# make device nodes. ticotsord and udp are necessary for
# 'ls' to resolve NIS names.
prefix="/devices/pseudo/mm@0:"

for device in zero
do
    line=`ls -l ${prefix}${device} | sed -e 's/,//'`
    major=`echo $line | awk '{print $5}'`
    minor=`echo $line | awk '{print $6}'`
    rm -f ${ftphome}/dev/${device}
    mknod ${ftphome}/dev/${device} c ${major} ${minor}
done

prefix="/devices/pseudo/clone@0:"

for device in tcp udp ticotsord
do
    line=`ls -l ${prefix}${device} | sed -e 's/,//'`
    major=`echo $line | awk '{print $5}'`
    minor=`echo $line | awk '{print $6}'`
    rm -f ${ftphome}/dev/${device}
    mknod ${ftphome}/dev/${device} c ${major} ${minor}
done
chmod 666 ${ftphome}/dev/*

## Now set the ownership and modes
chown root ${ftphome}/dev
chmod 555 ${ftphome}/dev

if [ ! -d ${ftphome}/pub ]; then
   mkdir -p ${ftphome}/pub
fi
chown ftp ${ftphome}/pub
chmod 777 ${ftphome}/pub

----------------------------------------------------------------------
20. eval 和 exec 的不同
    eval 只是去執行後面的命令,但是 exec 會執行該命令後跳出 shell
    看例子就知道

#!/bin/sh
echo "Input command : \n"
read cmd
eval $cmd
# 底下會執行
echo "You can see this line ..after executing $cmd"


#!/bin/sh
echo "Input command : \n"
read cmd
exec $cmd
# 底下不會執行
echo "You can not see this line ..after executing $cmd"

----------------------------------------------------------------------
21. 字串連接, 如下,最後會印出 /etc/yp

yproot_dir=/etc
def_dom=yp
domain_dir="$yproot_dir""/""$def_dom"
echo $domain_dir

----------------------------------------------------------------------
22. case , if , function 綜合用法

#!/bin/sh

killproc() {            # kill the named process(es)
pid=`ps -e | grep $1 | sed -e 's/^  *//' -e 's/ .*//'`

# 請特別注意 $pid 和 "$pid" 居然不同,我也不懂

#if [ $pid = "" ]; then
if [ "$pid" = "" ]; then
  echo "Can't find process \"$1\" "; exit 2
fi

echo "kill the process \"$1\" with PID $pid"; kill $pid 2> /dev/null
}

case $# in
  1)
    killproc $1
    ;;
  *)
    echo "usage: $0 daemon-name"
    ;;
esac

----------------------------------------------------------------------
23. 將大寫檔名改成小寫檔名
    tr string1 string2 會將 standard input內所對應到的 string1
    都以 string2 取代

for file in *; do
   mv $file `echo $file | tr '[A-Z]' '[a-z]'`
done


加上一點變化,只處理大寫的檔名,不過執行過後,第二次會有問題,還不是很懂
for file in [A-Z]*; do
   echo "process $file"
   mv $file `echo $file | tr '[A-Z]' '[a-z]'`
done

----------------------------------------------------------------------
24. case 的變化,一個轉換西元到民國的範例
    [0-9][0-9] 表示有兩個存在的數,
    [0-9][0-9][0-9][0-9] 表示有四個存在的數
    當然也可以 [a-Z] [a-A]等等的變化了
    不懂的地方是 echo 1>&2 這個敘述

echo "Input year : \c"
read year
case "$year" in
  [0-9][0-9])
     year=19${year}
     years=`expr $year - 1911`
     ;;
  [0-9][0-9][0-9][0-9])
     years=`expr $year - 1911`
     ;;
  *)
     echo 1>&2 Year \"$year\" out of range ...
     exit 127
     ;;
esac
echo "$year 是民國 $years"

----------------------------------------------------------------------
25. if 內有兩個判斷式的寫法

echo "Input year : \c"
read year
if [ $year -lt 1901  -o  $year -gt 2099 ]; then
   echo 1>&2 Year \"$year\" out of range
   exit 127
fi

----------------------------------------------------------------------
26. 處理一些多選一的字元

read next
case "$next" in
   *[A-Za-z]*)  echo "a-z A-Z"
                ;;
   *[0-9]*)     echo "0-9"
                ;;
   *)           echo "others.."
esac

----------------------------------------------------------------------
27. 7-Apr, 2003 新增

#!/bin/sh

# absolutly path condition
if [ -z `echo $1 | awk -F / {'print $1'}` ]; then
   if [ -x $1 ]; then
      echo "Yes, $1 is executable"
   fi

# others
else
   for foo in `echo $PATH | sed -e 's/:/ /g'` ; do
     # echo "searching $foo directory"
     if [ -x $foo/$1 ]; then
       echo "--> $foo/$1 is executable"
       exit
     fi
   done
fi

沒有留言:

搜尋此網誌