zoukankan      html  css  js  c++  java
  • Shell变量知识进阶

    一,Shell中特殊且重要的变量

    $0结合dirname和basename分别取出脚本名称和脚本路径

    [root@192-168-3-163 scripts]# cat test.sh
    #!/bin/bash
    dirname $0
    basename $0
    
    [root@192-168-3-163 scripts]# sh /mnt/scripts/test.sh 
    /mnt/scripts
    test.sh

    也可参考系统rpcbind脚本

    echo $"Usage: $0 {start stop | status | restart | reload }"

    $n测试

    [root@192-168-3-163 mnt]# cat test.sh 
    echo $1 $2 $3 $4 $5 $6 $7 $8 $9 $10 $11 $12 $13 $14 $15
    
    [root@192-168-3-163 mnt]# sh  test.sh  1 5 6  #传入3个参数,结果显示有误
    1 5 6 10 11 12 13 14 15
    
    [root@192-168-3-163 mnt]# cat test.sh #$9以上的参数用大括号括起来结果输出正常
    echo $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} ${11} ${12} ${13} ${14} ${15}
    [root@192-168-3-163 mnt]# sh  test.sh  1 5 6
    1 5 6

    脚本参考案例

    case "$1" in
        start)
            if [ -f $PIDFILE ]
            then
                echo "$PIDFILE exists, process is already running or crashed"
            else
                echo "Starting Redis server..."
                $EXEC $CONF
            fi
            ;;
        stop)
            if [ ! -f $PIDFILE ]
            then
                echo "$PIDFILE does not exist, process is not running"
            else
                PID=$(cat $PIDFILE)
                echo "Stopping ..."
                $CLIEXEC -p $REDISPORT shutdown
                while [ -x /proc/${PID} ]
                do
                    echo "Waiting for Redis to shutdown ..."
                    sleep 1
                done
    

    $# 特殊变量获取脚本传参个数的实践

    [root@192-168-3-163 scripts]# cat test.sh 
    #!/bin/bash
    echo $1 $2 $3 $4 $5 
    echo $#
    [root@192-168-3-163 scripts]# sh test.sh {1..10}  #传入10个参数
    1 2 3 4 5 #接收5个
    10 #打印参数总数10个  

    范例

    [root@192-168-3-163 scripts]# cat test.sh 
    #!/bin/bash
    [ $# -ne 2 ] && {  #如果执行脚本参数的个数不等于2
    
      echo "must be two args"
      exit 1  #给出上面提示 退出
    
    }
    echo Beijing #满足参数要求后 打印
    

      

    if判断写法

    [root@192-168-3-163 scripts]# cat test.sh 
    #!/bin/bash
    if [ $# -ne 2 ]  #如果参数不等于2
      then
        echo "USAGE:/bin/sh $0 arg1 arg2" #如果不满足参数提示用法
        exit 1
    fi
    echo $1 $2
    

    $*和$@特殊变量功能及区别说明

    范例 利用set设置位置参数(同命令行脚本的传参)

    [root@192-168-3-163 scripts]# set -- "I am" handsome boy
    [root@192-168-3-163 scripts]# echo $#          #输出参数个数
    3
    [root@192-168-3-163 scripts]# echo $1
    I am
    [root@192-168-3-163 scripts]# echo $2
    handsome
    [root@192-168-3-163 scripts]# echo $3
    boy
    [root@192-168-3-163 scripts]# 
    

    测试$*和$@,注意此时不带双引号

    [root@192-168-3-163 scripts]# set -- "I am" handsome boy
    [root@192-168-3-163 scripts]# echo $*
    I am handsome boy
    [root@192-168-3-163 scripts]# echo $@
    I am handsome boy
    [root@192-168-3-163 scripts]# for i in $*; do echo $i; done
    I
    am
    handsome
    boy
    [root@192-168-3-163 scripts]# for i in $@; do echo $i; done
    I
    am
    handsome
    boy
    #上面测试结果相同

    测试“$*” 和“$@”,注意,此时带有双引号:

    [root@192-168-3-163 scripts]# set -- "I am" handsome boy
    [root@192-168-3-163 scripts]# echo "$*"
    I am handsome boy
    [root@192-168-3-163 scripts]# echo "$@"
    I am handsome boy
    [root@192-168-3-163 scripts]# for i in "$*";do echo $i;done #当做一个参数输出
    I am handsome boy
    [root@192-168-3-163 scripts]# for i in "$@";do echo $i;done
    I am
    handsome
    boy
    #每个参数均独立输出
    

     

    Shell进程中的特殊状态变量

    $?   获取执行上一个指令的执行状态返回值(0为成功,非零为失败)
    $$   获取当前执行的Shell脚本的进程(PID)
    $!    获取上一个在后台工作的进程的进程号(PID)
    $_   获取在此之前执行的命令或脚本的最后一个参数
    

    在企业场景下,“$?” 返回值的用法如下:

    1.判断命令、脚本或函数等程序是否执行成功

    2.若在脚本中调用执行“exit 数字”,则会返回这个数字给“$?”变量

    3.如果是在函数里,则通过“return数字” 把这个数字以函数返回值的形式传给“$?”

    stop() {
    	echo -n $"Stopping $prog: "
    	killproc $prog #这个是停止rpcbind的命令
    	RETVAL=$?     #将上述命令的返回值"$?" 赋值给RETVAL变量,用于后面的判断
    	echo
    	[ $RETVAL -eq 0 ] && {  #这里判断,如果返回0,执行下面指令
    		rm -f /var/lock/subsys/$prog
    		rm -f /var/run/rpcbind*
    	}
    	return $RETVAL #如果返回值不等于0,则跳过条件表达式判断,在这里直接作为返回值传给执行stop函数的脚本
    }  

    $$特殊变量功能及实践

    [root@192-168-3-163 scripts]# more test.sh 
    #!/bin/bash
    echo $$ > /tmp/a.pid  #把进程id写入到文件
    sleep 300  
    [root@192-168-3-163 scripts]# sh test.sh &
    [1] 11485          
    [root@192-168-3-163 scripts]# cat /tmp/a.pid 
    11485
    

      

    范例

    [root@192-168-3-163 scripts]# cat test.sh 
    #!/bin/bash
    pidpath=/tmp/a.pid #定义pid文件
    if [ -f "$pidpath" ] #如果存在,执行下面then语句
      then
        kill -9  `cat $pidpath` > /dev/null 2>&1 #杀掉与前一个进程号对应的进程
        rm -f $pidpath
    fi
    echo $$ > $pidpath
    sleep 300
    [root@192-168-3-163 scripts]# sh test.sh &
    [3] 12654
    [2]-  Killed                  sh test.sh
    [root@192-168-3-163 scripts]# sh test.sh &
    [4] 12668
    [3]-  Killed                  sh test.sh
    [root@192-168-3-163 scripts]# ps aux |grep test.sh |grep -v grep
    root     12668  0.0  0.0 113128  1408 pts/1    S    16:50   0:00 sh test.sh
    
    #无论运行多少此脚本,都只有一个进程
    *提示:这个是一个生产案例的简单模拟,脚本用于执行启动或者定时任务时,相同的脚本中只能有一个运行,当新脚本运行时,必须关闭未运行完成或未退出的上一次的同名脚本进程

    内置变量命令

    echo 
    -n   不换行输出内容
    -e   解析转义字符(如下面的字符)
    
    
     换行
    
      回车
    	  制表符
     退格
    v 纵向制表符
    

      

    范例

    [root@192-168-3-163 scripts]# echo beijing;echo shanghai
    beijing
    shanghai
    [root@192-168-3-163 scripts]# echo -n beijing;echo shanghai
    beijingshanghai
    [root@192-168-3-163 scripts]# echo "beijing	shanghai
    nanjing	hangzhou"
    beijing	shanghai
    nanjing	hangzhou
    [root@192-168-3-163 scripts]# echo -e "beijing	shanghai
    nanjing	hangzhou"
    beijing	shanghai
    nanjing	hangzhou
    

      

    exec使用

    命令格式:exec命令参数

    功能:exec 命令能够在不创建新的子进程的前提下,转去执行指定的命令,当指定的命令执行完毕后,改进程(也就是最初的Shell)就终止了。

    当使用exec 打开文件后,read命令每次都会将文件指针移动到文件的下一行进行读取,直到文件末尾,利用这个可以实现处理文件内容。

    范例:

    [root@192-168-3-163 ~]# cat /tmp/tmp.log 
    1
    2
    3
    4
    5
    [root@192-168-3-163 ~]# cat exec.sh 
    #!/bin/bash
    exec < /tmp/tmp.log
    while read line
      do 
        echo $line
    done
    echo ok
    [root@192-168-3-163 ~]# sh exec.sh 
    1
    2
    3
    4
    5
    ok
    

    shift 命令使用

    [root@192-168-3-163 scripts]# cat test.sh 
    #!/bin/bash
    echo $1 $2
    if [ $# -eq 2 ]
      then
        shift
        echo $1
    fi
    [root@192-168-3-163 scripts]# sh test.sh 1 2
    1 2
    2

    应用场景:当我们写Shell希望像命令行的命令通过参数控制不同的功能时,就会先传一个类似-c的参数,然后再接内容。

    [root@192-168-3-163 scripts]# cat test.sh 
    #!/bin/bash
    echo $1 $2
    if [ $# -eq 2 ]
      then
        shift
        echo $1
    fi
    [root@192-168-3-163 scripts]# sh test.sh 1 2
    1 2
    2
    [root@192-168-3-163 scripts]# sh test.sh -c 1
    -c 1
    1
    

     

    可以参考ssh-copy-id -i /root/.ssh/id_dsa.pub

    [root@192-168-3-163 scripts]# sed -n '105,122p'  /usr/bin/ssh-copy-id 
      case "$1" in
        -i?*|-o?*|-p?*)
          OPT="$(printf -- "$1"|cut -c1-2)"
          OPTARG="$(printf -- "$1"|cut -c3-)"
          shift
          ;;
        -o|-p)
          OPT="$1"
          OPTARG="$2"
          shift 2
          ;;
        -i)
          OPT="$1"
          test "$#" -le 2 || expr "$2" : "[-]" >/dev/null || {
            OPTARG="$2"
            shift
          }
          shift
    

      作用:方便

    有关set和eval命令的使用案例(特殊位置的变量用法)参考http://oldboy.blog.51cto.com/2561410/1175971

  • 相关阅读:
    Shiro权限管理框架(二):Shiro结合Redis实现分布式环境下的Session共享
    Shiro权限管理框架(一):Shiro的基本使用
    【自动化__持续集成】___java___finally
    【自动化__持续集成】___java___异常处理
    【自动化__持续集成】___java___static
    【自动化__持续集成】___java___对象
    【自动化__持续集成】___java___代码非空指针
    【自动化__持续集成】___java___代码空指针
    【自动化__持续集成】___java___失血模型
    【自动化__持续集成】___java___构造方法
  • 原文地址:https://www.cnblogs.com/xiewenming/p/8544872.html
Copyright © 2011-2022 走看看