shell学习四-----特殊变量二

时间:2023-01-17 15:33:57
7、学习使用系统脚本
/etc/init.d/rpcbind                
[root@node01 day2]# vi /etc/init.d/rpcbind 
#! /bin/sh
#
# rpcbind       Start/Stop RPCbind
#
# chkconfig: 2345 13 87
# description: The rpcbind utility is a server that converts RPC program \
#              numbers into universal addresses. It must be running on the \
#              host to be able to make RPC calls on a server on that machine.
#
# processname: rpcbind
# probe: true
# config: /etc/sysconfig/rpcbind

# This is an interactive program, we need the current locale
[ -f /etc/profile.d/lang.sh ] && . /etc/profile.d/lang.sh
# We can't Japanese on normal console at boot time, so force LANG=C.
if [ "$LANG" = "ja" -o "$LANG" = "ja_JP.eucJP" ]; then
    if [ "$TERM" = "linux" ] ; then
        LANG=C
    fi
fi


# Source function library.
. /etc/init.d/functions


# Source networking configuration.
[ -f /etc/sysconfig/network ] &&  . /etc/sysconfig/network


prog="rpcbind"
[ -f /etc/sysconfig/$prog ] && . /etc/sysconfig/$prog


RETVAL=0
uid=`id | cut -d\( -f1 | cut -d= -f2`


start() {
        # Check that networking is up.
        [ "$NETWORKING" = "yes" ] || exit 6


        [ -f /sbin/$prog ] || exit 5


        # Make sure the rpcbind is not already running.
        if status $prog > /dev/null ; then
                exit 0
        fi


        # Only root can start the service
        [ $uid -ne 0 ] && exit 4


        echo -n $"Starting $prog: "
        daemon $prog $1 "$RPCBIND_ARGS"
        RETVAL=$?
        echo
        if [ $RETVAL -eq 0 ] ; then       成功了,就创建一个文件,这里写脚本写个plog,启动建立,停止删掉
                touch /var/lock/subsys/$prog
                [ ! -f /var/run/rpcbind.pid ] &&
                        /sbin/pidof $prog > /var/run/rpcbind.pid
        fi
        return $RETVAL
}


stop() {
        echo -n $"Stopping $prog: "
        killproc $prog
        RETVAL=$?
        echo
        [ $RETVAL -eq 0 ] && {
                rm -f /var/lock/subsys/$prog   成功了,就创建一个文件,这里写脚本写个plog,启动建立,停止删掉
                rm -f /var/run/rpcbind*
        }
        return $RETVAL
}


# See how we were called.
case "$1" in                                  接传参,如果是以下的就执行。
  start)
        start
        RETVAL=$?                             返回值给一个变量,返回给当前shell
        ;;
  stop)
        stop
        RETVAL=$?
        ;;
  status)
        status $prog
        RETVAL=$?
        ;;
  restart | reload| force-reload)
        stop
        start
        RETVAL=$?
        ;;
  condrestart | try-restart)
        if [ -f /var/lock/subsys/$prog ]; then
                stop
                start -w
                RETVAL=$?
        fi
        ;;
  *)
        echo $"Usage: $0 {start|stop|status|restart|reload|force-reload|condrestart|try-restart}"   $0这里表示命令自己
        RETVAL=2
        ;;
esac


exit $RETVAL


执行命令:
[root@node01 day2]# /etc/init.d/rpcbind start   这个start就是上面$1接收传参


[root@node01 day2]# /etc/init.d/rpcbind dddd fkdjkj  kjkjf
Usage: /etc/init.d/rpcbind {start|stop|status|restart|reload|force-reload|condrestart|try-restart}
[root@node01 day2]# 
[root@node01 day2]# /etc/init.d/rpcbind status
rpcbind (pid  1292) is running...
=======================================================================
8、$*和$@的区别(了解)
$*获取shell的所有传参,将所有的参数视为单个字符串,相当于“$1$2$3"
$@他把所有参数显示为“$1" “1"  ”$3"
注意:上述区别在于加双引号的时候,即“$*" 和"$@"
例子:
[root@node01 day2]# set -- "lao lang"  welcome to beijing  传入4个参数
[root@node01 day2]# echo $#                                打印参数
4
[root@node01 day2]# for i in "$*";do echo $i;done
lao lang welcome to beijing
[root@node01 day2]# for i in "$@";do echo $i;done  在有双引号的情况下去处理,每个单数独立输出
lao lang
welcome
to
beijing
[root@node01 day2]# for i in "$@";do echo $i;done 
lao lang
welcome
to
beijing


[root@node01 day2]# for i in $*;do echo $i;done   在没有双引号的情况下,把参数分开了,这样“$*" 和"$@"结果一样了
lao
lang
welcome
to
beijing
[root@node01 day2]# for i in $@;do echo $i;done  
lao
lang
welcome
to
beijing
=====================================================================
9、移动位置变量  内置变量
[root@node01 day2]# shift
[root@node01 day2]# for i in $@;do echo $i;done
welcome
to
beijing
[root@node01 day2]# shift
[root@node01 day2]# for i in $@;do echo $i;done
to
beijing
[root@node01 day2]# shift
[root@node01 day2]# for i in $@;do echo $i;done
beijing
[root@node01 day2]# shift
[root@node01 day2]# for i in $@;do echo $i;done


[root@node01 day2]# help shift
shift: shift [n]
    Shift positional parameters.
    
    Rename the positional parameters $N+1,$N+2 ... to $1,$2 ...  If N is
    not given, it is assumed to be 1.
    
    Exit Status:
    Returns success unless N is negative or greater than $#.
例子
[root@node01 day2]# vim `which ssh-copy-id`
#!/bin/sh


# Shell script to install your public key on a remote machine
# Takes the remote machine name as an argument.
# Obviously, the remote machine must accept password authentication,
# or one of the other keys in your ssh-agent, for this to work.


ID_FILE="${HOME}/.ssh/id_rsa.pub"


if [ "-i" = "$1" ]; then                                 如果$1是-i做shift
  shift
  # check if we have 2 parameters left, if so the first is the new ID file
  if [ -n "$2" ]; then
    if expr "$1" : ".*\.pub" > /dev/null ; then
      ID_FILE="$1"
    else
      ID_FILE="$1.pub"
    fi
    shift         # and this should leave $1 as the target name
  fi
else
  if [ x$SSH_AUTH_SOCK != x ] ; then
    GET_ID="$GET_ID ssh-add -L"
  fi
fi
if [ -z "`eval $GET_ID`" ] && [ -r "${ID_FILE}" ] ; then
  GET_ID="cat ${ID_FILE}"
fi


if [ -z "`eval $GET_ID`" ]; then
  echo "$0: ERROR: No identities found" >&2
  exit 1
fi


if [ "$#" -lt 1 ] || [ "$1" = "-h" ] || [ "$1" = "--help" ]; then
  echo "Usage: $0 [-i [identity_file]] [user@]machine" >&2
  exit 1
fi


{ eval "$GET_ID" ; } | ssh $1 "umask 077; test -d ~/.ssh || mkdir ~/.ssh ; cat >> ~/.ssh/authorized_keys && (test -x /sbin/restorecon && /sbin/restorecon ~/.ssh ~/.ssh
/authorized_keys >/dev/null 2>&1 || true)" || exit 1


cat <<EOF
Now try logging into the machine, with "ssh '$1'", and check in:


  .ssh/authorized_keys


to make sure we haven't added extra keys that you weren't expecting.


EOF
                                                                                                                                                     50,1          Bot


if [ -z "`eval $GET_ID`" ]; then
  echo "$0: ERROR: No identities found" >&2
  exit 1
fi


if [ "$#" -lt 1 ] || [ "$1" = "-h" ] || [ "$1" = "--help" ]; then
  echo "Usage: $0 [-i [identity_file]] [user@]machine" >&2
  exit 1
fi


{ eval "$GET_ID" ; } | ssh $1 "umask 077; test -d ~/.ssh || mkdir ~/.ssh ; cat >> ~/.ssh/
authorized_keys && (test -x /sbin/restorecon && /sbin/restorecon ~/.ssh ~/.ssh/authorized
_keys >/dev/null 2>&1 || true)" || exit 1


cat <<EOF
Now try logging into the machine, with "ssh '$1'", and check in:


  .ssh/authorized_keys


to make sure we haven't added extra keys that you weren't expecting.


EOF

===========================================================================
10、其他
$$ 获取当前shell的进程号(PID):当系统中只能同时运行一个相同的脚本
例子:
[root@node01 ~]# vi p.sh
echo 1
sleep 300
~             
[root@node01 day2]# sh pid.sh &
[2] 10621
[root@node01 day2]# 
[root@node01 day2]# ps -ef |grep pid.sh
root      10621  10581  0 10:33 pts/1    00:00:00 sh pid.sh
root      10627  10581  0 10:33 pts/1    00:00:00 grep pid.sh
[root@node01 day2]# vi pid.sh 
echo $$ >/tmp/a.pid
sleep 300
[root@node01 day2]# sh pid.sh &
[3] 10630
[root@node01 day2]# kill -USR2 `cat /tmp/a.pid`
[root@node01 day2]# ps -ef |grep pid.sh|grep -v grep
[root@node01 day2]# cat pid.sh 
[root@node01 day2]# vi pid.sh  
#!/bin/sh
pidpath=/tmp/a.pid
if [ -f "$pidpath" ]
  then
      kill -USR2 `cat $pidpath` >/dev/null 2>&1
      rm -f $pidpath
fi
echo $$ >$pidpath
sleep 300
~         
[root@node01 day2]# ps -ef |grep pid.sh|grep -v grep
root      10743      1  0 10:48 ?        00:00:00 sh pid.sh
$! 执行上一个指令的PID
$_ 再此之前执行的命令或者脚本的最后一个参数
=========================================================================
以上变量重要程度

$?>$n>$#>$0

=========================================================================

 总结:                  
变量 含义 
$0 当前脚本的文件名 
$n 传递给脚本或函数的参数。n 是一个数字,表示第几个参数。例如,第一个参数是$1,第二个参数是$2。 
$# 传递给脚本或函数的参数个数。 
$* 传递给脚本或函数的所有参数。 
$@ 传递给脚本或函数的所有参数。被双引号(" ")包含时,与 $* 稍有不同,下面将会讲到。 
$? 上个命令的退出状态,或函数的返回值。 
$$ 当前Shell进程ID。对于 Shell 脚本,就是这些脚本所在的进程ID。