Shell编程基础篇

ew3y 10年前

1.变量
    用户自定义变量
        用户可以按照下面的语法规则定义自己的变量:变量名=变量值 。要注意的一点是,在定义变量时,变量名前不应加符号“$”,在引用变量的内容时则应在变量名前加“$”;在给变量赋值时,等号两边一定不能留空格,若变量中本身就包含了空格,则整个字符串都要用双引号括起来。
    位置变量
        通过命令行给程序传递执行参数。
            $0:当前执行的进程/程序名
            $n:(n为1-9的数字)第几个位置参数
    预定义变量
        $#:命令行中位置参数的个数
        $:所有位置参数的内容
        $?:上一条命令执行后返回的状态,当执行成功时返回0,不成功返回非0
        $n:位置参数变量
        $$:当前进程的id
        $!:最后一个后台进程的id
    环境变量
        在开始执行时就已经定义了一些和系统的工作环境有关的变量,这些变量用户还可以重新定义。
            HOME:用于保存注册目录的完全路径名。
            PATH:用于保存用冒号分隔的目录路径名,shell将按PATH变量中给出的顺序搜索这些目录,找到的第一个与命令名称一致的可执行文件将被执行。
            TERM:终端的类型。
            UID:当前用户的标识符,取值是由数字构成的字符串。
            PWD:当前工作目录的绝对路径名,该变量的取值随cd命令的使用而变化。
            PS1:主提示符,在特权用户下,缺省的主提示符是“#”,在普通用户下,缺省的主提示符是“$”。

            PS2:在shell接收用户输入命令的过程中,如果用户在输入行的末尾输入“\”然后回车,或者当用户按回车键时shell判断出用户输入的命令没有结束时,显示这个辅助提示符,提示用户继续输入命令的其余部分,缺省的辅助提示符是“>”。

2.算数运算符
    (())
        例如
            1.((i=$j+$k))     等价于   i=expr $j + $k  
            2.((i=$j-$k))     等价于   i=expr $j - $k
            3.((i=$j
$k))     等价于   i=expr $j \* $k
            4.((i=$j/$k))     等价于   i=expr $j / $k
    $(())
        例如
            1.echo $((1+2))
            2.echo $((1-2))
            3.echo $((12))
            4.echo $((1/2))
    let
        例如
            1.let i=1+2
            2.let i=1-2
            3.let i=1
2
            4.let i=1
            5.let "i=1+1"
            6.let "i = 1 + 1"
            7.let i=1+1
            8.let "i = i + 1"
            9.let i=i+1
    expr
        例如:
            1.sum=$(expr $num1 + $num2)
    declare
        例如:
            1.num1=123
              num2=456
              declare -i sum=$num1+$num2
    注意:
        1.在括号运算中((i=$j+$k))运算符号两边可以有空格也可以没有空格,但是expr运算i=expr $j + $k中运算符号两边必须要有空格!
        2.乘法运算符号是 \
,而不是
        3.除法运算 / 表示整除,1/2=0
        4.let表达式中的变量前不必有$
        5.如果表达式中包含了空格或其他特殊字符,则必须引起来。(let i=i+1中除了let后面有一个空格外,其他地方不能有一个空格!) </p>

3.条件测试
    test
        用途:测试特定的表达式是否成熟,当条件成立时,命令执行后的返回值为0,否则为其他数字。
        格式: test 条件表达式 或者 [ 条件表达式 ]
        常见的测试操作符
            -d:测试是否为目录
            -e:测试目录或者文件是否存在
            -f:测试是否为文件
            -r:测试当前用户是否有权限读取
            -w:测试当前用户是否有权限写入
            -x:测试当前用户是否可执行该文件
           -L:测试是否为符号连接文件
    例如:
        if [ -f ./file ];then
            echo "exists!"
        else
            echo "not exists!"
        fi
     整数值比较
        格式:[ 整数1 操作符 整数2 ]
        常用的测试操作符
            -eq:等于
            -ne:不大于
            -gt:大于
            -lt:小于
            -le:小于或等于
            -ge:大于或等于
    例如:
        if [ 30 -ge 12 ];then
            echo '30 > 12'
        else
            echo '30 < 12'
        fi
    字符串比较
        格式:[ 字符串1 = 字符串2 ] [ 字符串1 != 字符串2 ] [ -z 字符串 ]
        常用的测试操作符
             =: 字符串内容相同
            !=: 字符串内容不同,
            -z: 字符串内容为空
    例如:
        if [ 'admin' = 'admin' ];then
            echo '相等'
        else
            echo ‘不相等’
        fi
    逻辑测试
        格式:[ 表达式1 ] 操作符 [ 表达式2 ] ...
        常用的操作符
            -a或者&&:逻辑与,前后两个表达式都成立时整个测试结果才为真,否则为假
            -o或者||:逻辑或,操作符两边至少一个为真时测试结果才为真,否则为假
            !:逻辑否,当指定的条件不成立时,返回结果为真
    例如:
        if [ 'admin' = 'admin' ] && [ 'pass' = 'pass' ];then
            echo '相等'
        else
            echo ‘不相等’
        fi流程判断
if
    例如:
        1.年龄判断
        if [ $age -lt 18 ];then
            echo '未成年'
        else
            echo '已成年'
        fi
        2.成绩级别
        if [ $score -lt 60 ];then
            echo '60以下'
        elif [ $score -lt 70 ];then
            echo '60-70'
        elif [ $score -lt 80 ];then
            echo '70-80'
        elif [ $score -lt 90 ];then
            echo '80-90'
        else
            echo '90-100'
        fi
case
    例如:
        1.星期几的判断
        case $week in
            1)
                echo '周一'
                ;;
            2)
                echo '周二'
                ;;
            3)
                echo '周三'
                ;;
            4)
                echo '周四'
                ;;
            5)
                echo '周五'
                ;;
            6)
                echo '周六'
                ;;
            7)
                echo '周七'
                ;;
            
)
                echo '其他'
                ;;
        esac </p>

5.循环控制
   while
    例如;
    1.
        while [ $num -gt 0 ]
        do
            echo $num
            num=$(($num-1))
        done
        echo $num
    2.
  for in
    例如:
    1.
        for i in user0 user1 user2
        do
            echo $i
        done
    2.
        for((i=0;i<10;i++))
        do
            echo $i
        done
    3.
        for i in `ls /etc`
        do
            echo $i
        done

6.shift、break、continue、exit

   shift
        例如:
        1.
            while [ $# -gt 0 ]
            do
                tot = $(($tot+$1))
                shift
            done
    break
        命令可以带一个参数,一个不带参数的break 循环只能退出最内层的循环,而break N可以退出N层循环。
        例如:
            1.
                #!/bin/sh  
                for i in "a b c d"
                do   
                echo "$i "
                 for j in `seq 10`  
                    do  
                      if [ $j -eq 5 ];then
                        break  
                      fi  
                      echo "$j "
                    done
                echo  
                done
            2.
                #!/bin/sh  
                for i in "a b c d"
                do   
                echo "$i "
                 for j in `seq 10`  
                    do  
                      if [ $j -eq 5 ];then
                        break 2
                      fi  
                      echo "$j "
                    done
                echo  
                done
    continue
        命令也可以带一个参数,一个不带参数的continue 命令只去掉本次循环的剩余代码,而continue N 将会把N层循环剩余的代码都去掉,但是循环的次数不变。
        例如:
            1.
                #!/bin/sh  
                for i in "a b c d"
                do   
                echo "$i "
                 for j in `seq 10`  
                    do  
                      if [ $j -eq 5 ];then
                        continue  
                      fi  
                      echo "$j "
                    done
                echo  
                done
            2.
                #!/bin/sh  
                for i in "a b c d"
                do   
                echo "$i "
                 for j in `seq 10`  
                    do  
                      if [ $j -eq 5 ];then
                        continue 2
                      fi  
                      echo "$j "
                    done
                echo  
                done

   exit

    在shell脚本中可以终止当前脚本执行。
    格式:exit n
    例如:
        1.exit 0
        2.
            if [ "$#" -ne "2" ]; then  
                echo "usage: $0 <area> <hours>"  
                exit 2  
            fi  
    注意:
        1.n为退出码
        2.退出码的约定:0表示成功;非0表示失败(2表示用法不当、127表示命令没有找到、126表示不是可执行的、>=128 信号产生)。

7.函数
    例如:
    1.
        // 函数定义
        function add(){
            echo 'aaaaaaaa'
        }
        // 函数调用
        add
    2.
        // 函数定义及传参
        function add(){
            num=$1 // 参数的调用类似于位置变量
            for((i=1;i<=$num;i++))
            do
                tot = $(($tot+$i))
            done
        }
        // 调用传参的函数
        add 100
    3.
        // 函数定义
        function add(){
            return 'aaaaaaaa'
        }
        // 函数调用
        add
        // 获取函数返回值
        echo $?
    注意:
        1、必须在调用函数地方之前,声明函数,因为shell脚本是逐行运行。不会像其它语言一样先预编译。所以必须在使用函数前先声明函数。

        2、total=$(add 100);  通过这种调用方法,我们清楚知道,在shell中单括号里面,可以是:命令语句。 因此,我们可以将shell中函数,看作是定义一个新的命令,它是命令,因此各个输入参数直接用空格分隔。命令里面获得参数方法可以通过:$0…$n得到。 $0代表函数本身。
        3、函数返回值,只能通过$? 系统变量获得,直接通过=,获得是空值。其实,我们按照上面一条理解,知道函数是一个命令,在shell获得命令返回值,都需要通过$?获得。

8.文件引用
    1. . filename
    2. source filename
    注意:
        两种方式的效果相同,简单起见,一般使用点号(.),但是注意点号(.)和文件名中间有一空格。