shell高级编程笔记(第八章 操作符和相关主题)

    技术2022-07-15  89

    第八章 操作符和相关主题

    8.1 操作符

    等号操作符

    = 变量赋值(初始化或修改变量的值) 无论在算术运算还是字符串运算中,都是赋值语句 #"="后边不能有空格

    var=27 category=minerals

    注意:不要和"="test操作符混淆

    算术操作符

    + 加法 - 减法 * 乘法 / 除法 ** 幂运算

    let "z=5**3" echo "z = $z" #z = 125

    % 取模

    expr 5 % 3 #2

    Example 8.1 最大公约数

    #!/bin/bash #gcd.sh :最大公约数 #最大公约数就是2个数能够同时整除的最大的数 #Euclid's算法采用连续除法 #在每个循环中被除数<--除数;除数<--余数;直到余数=0 #在最后的循环中The gcd=被除数 #参数检查 ARGS=2 E_BADARGS=65 if [ $# -ne "$ARGS" ];then echo "用法:`basename $0` 第一个整数 第二个整数" exit $E_BADARGS fi #练习:确保参数都是整数 E_NOINT=66 FIRST_NUMBER=`echo $1%1 |bc` SECOND_NUMBER=`echo $2%1 |bc` if [ "$FIRST_NUMBER" == 0 -a "$SECOND_NUMBER" == 0 ] then : else echo "Usage:`basename $0` 第一个整数 第二个整数" exit $E_NOINT fi gcd() { dividend=$1 #随便给值 divisor=$2 remainder=1 #如果在循环中使用未初始化的变量,那将在第一次的循环中产生一个错误消息 until [ "$remainder" -eq 0 ] do let "remainder = $dividend % $divisor" dividend=$divisor divisor=$remainder done } gcd $1 $2 echo;echo "GCD of $1 and $2 = $dividend";echo exit 0

    += 加等于(通过常量增加变量)

    let "var += 5" #var在本身的基础上增加5

    -= 减等于 *= 乘等于

    let "var *= 4"

    /= 除等于 %= 取模赋值,算术操作经常使用expr或者let表达式

    Example 8.2 使用算术操作符

    #!/bin/bash # n=1 echo -n $n let "n = $n +1" #let "n = n +1" 这么写也可以 echo -n $n : $((n = $n +1)) #:是必须的,如果没有:,Bash将尝试把$((n = $n +1))解释成一个命令 echo -n $n (( n = n + 1 )) #对于上边的方法的一个简单的选择 n=$(($n+1)) echo -n $n : $[n = $n + 1] #:是必须的 echo -n $n n=$[$n +1] echo -n $n #现在来个C分格的增量操作 let "n++" echo -n "$n" ((n++)) echo -n "$n" : $((n++)) echo -n "$n" : $[n++] echo -n "$n" echo exit 0

    注意:在Bash中的整型变量事实上是32位的,范围是-2147483648到2147483647,如果超过这个范围进行算术操作的话,会报错

    注意:Bash并不能理解浮点运算。它会把包含小数点看做字符串。如果真想做浮点运算的话,使用bc(见12.8节),bc可以进行浮点运算或调用数学库函数

    位操作符

    位操作符在shell脚本中极少使用。它最主要的用途看起来就是操作和test从sockets中读出的变量。"Bit flipping"与编译语言的联系很紧密,比如c/c++,在这种语言中它可以运行的足够块 << 左移一位(每次左移都将乘2) <<= 左移几位,=后边将给出左移几位

    let "var <<=2" 就是左移2(就是乘4)

    >> 右移1位(每次右移都将除2) >>= 右移几位 & 按位与 &= 按位与赋值 | 按位或 |= 按位或赋值 ~ 按位非 ! 按位否 ^ 按位异或XOR ^= 异或赋值

    逻辑操作

    && 逻辑与

    if [ $condition1 ] && [ $condition2 ] #与if [ $condition1 -a $condition2]相同 #if [[ $condition1 && $condition2 ]] 也可以 #注意:&&不允许出现在[...]中

    || 逻辑或

    if [ $condition1 ] || [ $condition2 ] #与if [ $condition1 -o $condition2]相同 #if [[ $condition1 || $condition2 ]] 也可以 #注意:||不允许出现在[...]中

    Example 8.3 使用&&和||进行混合状态的test

    #!/bin/bash # a=24 b=47 if [ $a -eq 24 ] && [ $b -eq 47 ];then echo "Test #1 succeeds." else echo "Test #1 fails." fi #尝试一(报错) if [ $a -eq 24 && $b -eq 47 ];then echo "Test 尝试一 succeeds." else echo "Test 尝试一 fails." fi #尝试二(可以使用) if [[ $a -eq 24 && $b -eq 47 ]];then echo "Test 尝试二 succeeds." else echo "Test 尝试二 fails." fi if [ $a -eq 89 ] || [ $b -eq 47 ];then echo "Test #2 succeeds." else echo "Test #2 fails." fi #-a和-o选项提供了一种可选的混合test方法 if [ $a -eq 24 -a $b -eq 47 ];then echo "Test #3 succeeds." else echo "Test #3 fails." fi if [ $a -eq 89 -o $b -eq 47 ];then echo "Test #4 succeeds." else echo "Test #4 fails." fi a=rhino b=crocodile if [ "$a" = rhino ] && [ "$b" = crocodile ];then echo "Test #5 succeeds." else echo "Test #5 fails." fi exit 0

    混杂操作

    , 逗号操作符 逗号操作符可以连接2个或多个算术运算。所有的操作都会被执行,但是只有最后一个操作作为结果

    let "t1=((5+3,7-1,15-4))" echo $t1 #11 let "t2=((a=9,15/3))" echo "t2=$t2 a=$a" #t2=5 a=9

    ","主要用在for循环中,具体见Example 10.12.

    8.2 数字常量

    shell脚本默认都是将数字作为10进制处理,除非这个数字某种特殊的标记法或者前缀开头。以0开头就是8进制。以0x开头就是16进制。使用BASE#NUMBER这种形式可以表示其他进制表示法

    Example 8.4 数字常量的处理

    #!/bin/bash #numbers.sh:数字常量的几种不同的表示法 #10进制:默认 let "dec=32" echo "decimal number=$dec" #32 #8进制:以0开头 let "oct=032" echo "octal number=$oct" #26 #表达式的结果用10进制表示 #16进制表示:数字以0x或者0X开头 let "hex=0x32" echo "hexadecimal number=$hex" #50 #其它进制:BASE#NUMBER #2-64进制都可以 #NUMBER必须在BASE的范围内 let "bin=2#11100111001101" echo "binary number=$bin" #331181 let "b32=32#77" echo "base-32 number=$b32" #231 let "b64=64#@_" echo "base-64 number=$b64" #4031 #这种64进制的表示法中的每位数字都必须在64进制表示法的限制字符内 #10个数字+26个小写字母+26个大写字母+@+_ echo echo $((36#zz)) $((2#10101010)) $((16#AF16)) $((53#1aA)) #1295 170 44822 3375 #注意:如果使用的每位数字超出了这个进制表示法规定字符的范围的话,将会给出一个错误。 let "bad_oct=081" #-bash: let: bad_oct=081: value too great for base (error token is "081") #值对于base太大(错误标记是“081”) exit 0
    Processed: 0.018, SQL: 9