• Linux shell编程学习笔记22: () $() (()) 的用法小结


    最近学习Linux Shell编程,对 () (()) [] [[]]等符号的用法还是有点分不太清楚,于是决定再梳理一下。今天先整理 () $() (()) 的用法。

    1 单小括号()

    1.1 子shell(命令组)


    括号中的命令将会新开一个子shell顺序执行,所以括号中的变量不能够被脚本余下的部分使用。括号中多个命令之间用分号隔开,最后一个命令可以没有分号,各命令和括号之间不必有空格。

    1.1.1 bash中

    $ bash
    [csdn ~]$ i=1; echo $i;(let i+=5; echo $i); echo $i
    1
    6
    1
    [csdn ~]$ 

     

    1.1.2 在zsh中

    # csdn @ edu in ~ [16:08:09] 
    $ i=1; echo $i;(let i+=5; echo $i); echo $i
    1
    6
    1

    在上面的实例中,执行命令i=1; echo $i 时变量i初始为1

    执行命令(let i+=5; echo $i);时,会创建一个子shell来执行,其中变量值i变为6

    最后执行命令echo $i,母shell中的变量i的值并没有继承子shell中的变化,仍然为1


    1.2 用于定义并初始化数组

    如:

    a=(1 2 3 4 a b c d)        

    定义了数组 a并初始化其中的元素值。

    1.3 用于条件判断

    1.3.1 bash中

    [csdn ~]$ i=1; if (test $i -lt 0); then; echo 'i<0'; else; echo 'i>=0'; fi
    bash: syntax error near unexpected token `;'
    [csdn ~]$ i=1;while (test $i -lt 10); do echo $i; let i++; done
    1
    2
    3
    4
    5
    6
    7
    8
    9

    1.3.2 在zsh中

    # csdn @ edu in ~ [19:00:25] C:1
    $ i=1; if (test $i -lt 0); then; echo 'i<0'; else; echo 'i>=0'; fi
    i>=0

    # csdn @ edu in ~ [19:00:46] 
    $ i=1;while (test $i -lt 10); do echo $i; let i++; done          
    1
    2
    3
    4
    5
    6
    7
    8
    9

    # csdn @ edu in ~ [19:00:52] 
    $ i=1;while (test $i < 10); do echo $i; let i++; done
    zsh: no such file or directory: 10

    # csdn @ edu in ~ [19:02:11] 
    $ i=1;while (test $i != 10); do echo $i; let i++; done
    1
    2
    3
    4
    5
    6
    7
    8
    9

    2 $():命令替换

    与` `(反引号)相似,都是用来作命令替换的,即,先完成()(小拓号)或` `(反引号)里的命令行,然后将其标准输出结果替换出来。

    2.1 在bash中

    [csdn ~]$ echo $(pwd;echo '\\n'; (cd /;echo path:;pwd); echo '\\n'; pwd)
    /home/csdn \\n path: / \\n /home/csdn
    [csdn ~]$ echo `pwd;echo '\\n'; (cd /;echo path:;pwd); echo '\\n'; pwd`
    /home/csdn \n path: / \n /home/csdn
    [csdn ~]$ echo `pwd;echo "\\n"; (cd /;echo path:;pwd); echo "\\n"; pwd`
    /home/csdn \n path: / \n /home/csdn
    [csdn ~]$ echo $(pwd;echo "\\n"; (cd /;echo path:;pwd); echo "\\n"; pwd)
    /home/csdn \n path: / \n /home/csdn
    [csdn ~]$ echo $(pwd;echo -e "\\n"; (cd /;echo path:;pwd); echo -e "\\n"; pwd)
    /home/csdn path: / /home/csdn
    [csdn ~]$ 

    在上面的实例中,我们先执行pwd命令显示当前目录路径:/home/csdn

    然后执行命令echo '\\n'来换行

    接着打开一个子shell执行命令: (cd /;echo path:;pwd); 其中命令cd /将当前目录改为/,再用pwd显示当前目录路径:/

    然后我们执行命令echo '\\n'来换行

    最后再用pwd显示当前目录路径:/home/csdn

    但是echo '\\n'命令没有实现换行,用了-e选项还是不行。

    2.2 在zsh中

    # csdn @ edu in ~ [17:21:47] 
    $ echo $(pwd;echo '\\n'; (cd /;echo path:;pwd); echo '\\n'; pwd)
    /home/csdn 
     path: / 
     /home/csdn

    # csdn @ edu in ~ [17:22:07] 
    $ echo `pwd;echo '\\n'; (cd /;echo path:;pwd); echo '\\n'; pwd`
    /home/csdn path: / /home/csdn

    同样的命令,在zsh中执行正确,换行也生效了。

    注:有些shell不支持这种使用方法,如tcsh。

    3 双小括号(()):整数运算、进制转换

    3.1 整数运算、比较

    3.1.1 在bash中

    # csdn @ edu in ~ [22:20:39] 
    $ bash
    [csdn ~]$ echo $((3+5))
    8
    [csdn ~]$ echo $((8 > 6))
    1
    [csdn ~]$ echo $((5+3 > 6))
    1
    [csdn ~]$ 

    3.1.2 在zsh中

    [csdn ~]$ zsh

    # csdn @ edu in ~ [22:19:50] 
    $ echo $((3+5))      
    8

    # csdn @ edu in ~ [22:20:11] 
    $ echo $((8 > 6))
    1

    # csdn @ edu in ~ [22:20:27] 
    $ echo $((3+5 > 6))
    1

    # csdn @ edu in ~ [22:20:39] 

    3.2 进制转换

    $(( ))可以将其他进制转成十进制数显示出来。用法如下:

    $((N#x))

    其中,N为进制,x为该进制下某个数值,命令执行后可以得到该进制数转成十进制后的值。
     

    3.2.1 在bash中

    $ bash
    [csdn ~]$ echo $((2#1000))
    8
    [csdn ~]$ echo $((8#1000))
    512
    [csdn ~]$ echo $((16#1000))
    4096
    [csdn ~]$ echo $((16#1000 - 1000))
    3096
    [csdn ~]$ echo $((16#1000 - 1000  > 2000)) 
    bash: 16#1000 - 1000  > 2000: syntax error: invalid arithmetic operator (error token is " > 2000")
    [csdn ~]$ echo $(((16#1000 - 1000)  > 2000)) 
    bash: (16#1000 - 1000)  > 2000: syntax error: operand expected (error token is " > 2000")
    [csdn ~]$ echo $(( $(16#1000 - 1000)  > 2000)) 
    bash: 16#1000: command not found
    bash:  > 2000: syntax error: operand expected (error token is " > 2000")
    [csdn ~]$ i=1000; $((16#$i-1000 > 2000))
    bash: 1: command not found
    [csdn ~]$ i=1000; $((16#${i}-1000 > 2000))
    bash: 1: command not found

    [csdn ~]$ echo $((16#1000  > 2000)) 
    bash: 16#1000  > 2000: syntax error: invalid arithmetic operator (error token is " > 2000")
    [csdn ~]$ 

    在bash中,可以顺利完成进制转换,进制转换和运算,但进制转换和比较不成功。

    3.2.2 在zsh中

    # csdn @ edu in ~ [15:08:45] C:1
    $ echo $((2#1000))
    8

    # csdn @ edu in ~ [15:08:52] 
    $ echo $((8#1000))
    512

    # csdn @ edu in ~ [15:09:00] 
    $ echo $((16#1000))
    4096

    # csdn @ edu in ~ [15:09:06] 
    $ echo $((16#1000 - 1000))
    3096

    # csdn @ edu in ~ [15:11:31] 
    $ echo $((16#1000 - 1000  > 2000)) 
    1

    在zsh中,可以顺利完成进制转换,进制转换和运算,进制转换、运算和比较。 

    在这点上,zsh表现优于bash。

    3.3 在(())中使用变量

    3.3.1 在bash中

    # csdn @ edu in ~ [15:24:06] 
    $ bash
    [csdn ~]$ i=5;echo $((i+9))
    14
    [csdn ~]$ i=12; echo $((8#i+9))
    bash: 8#i: value too great for base (error token is "8#i")
    [csdn ~]$ i=12; echo $((8#${i}+9))
    19
    [csdn ~]$ i=12; echo $((8#$i+9))
    19
    [csdn ~]$ i=12; echo $((8#$i+9 > 10))
    1
    [csdn ~]$ 

    3.3.2 在zsh中

     csdn @ edu in ~ [15:22:38] 
    $ i=5; echo $((i+9))
    14

    # csdn @ edu in ~ [15:23:00] 
    $ i=12; echo $((8#i+9))
    zsh: bad math expression: operator expected at `i+9'

    # csdn @ edu in ~ [15:23:23] C:1
    $ i=12; echo $((8#${i}+9)) 
    19

    # csdn @ edu in ~ [15:23:34] 
    $ i=12; echo $((8#${i}+9 > 10))
    1

    在bash和zsh中,在 (( )) 中使用变量一般不需要加上$前缀,(( )) 会自动解析变量名,这使得代码更加简洁,也符合程序员的书写习惯。

    但也有例外。比如:

    i=12; echo $((8#i+9))

    bash和zsh都无法识其中的变量i,于是我们要 用 $i 或 ${i}把变量i标记出来。

    3.4 总结

    shell类型整数运算比较算术&比较进制转换进制转换&算术&比较
    bash×
    zsh

    3.5 注意

    (( )) 只能用于整数算,不能用于小数(浮点数)或者字符串。要进行小数运算,可以使用 bc 命令。

  • 相关阅读:
    Web漏洞之XXE初探
    【深度学习21天学习挑战赛】8、卷积神经网络(认识Xception模型):动物识别
    详细了解关于sentinel的实际应用
    简单介绍ogb包(open graph benchmark)(图神经网络的基准数据集)
    轻量级的VsCode为何越用越大?为什么吃了我C盘10G?如何无痛清理VsCode缓存?手把手教你为C盘瘦身
    GemBox.Bundle 47.0.1227 Crack
    2023最新SSM计算机毕业设计选题大全(附源码+LW)之java校内考研吧hd450
    linux shell操作 - 04 进程间通信
    【Vue项目复习笔记】商品评论信息的展示
    手机注册卡知多少
  • 原文地址:https://blog.csdn.net/Purpleendurer/article/details/134275544