前言:在bash中遇到各种括号,同时在进行字符数值比较判定时,总是不断出现问题,于是通过参考《advanced bash-scripting guide》,同时在centos 6.7版本上进行测试,现况总结如下。如有纰漏,望指正。

一.()

一个命令组合,相当于一个命令组

[root@mghuee~chunlanyy testdir]# I=123;(I=xyz;echo $I;);echo $Ixyz123

二.{}

同"{}",也为一个命令组合,与"()"的区别就是前者在是当前shell中进行,而后者在里面子shell中进行

[root@mghuee~chunlanyy testdir]# I=123;(echo $I;I=xyz;echo $I;);echo $I123xyz123[root@mghuee~chunlanyy testdir]# I=123;{ echo $I;I=xyz;echo $I; };echo $I123xyzxyz

从例子中可以看得,"()"中的赋值只能影响到自身子shell,并不会赋值给父shell,而"{}"则只是在同一shell进行

另外需要注意的是,"{}"是一个keyword,所以在命令与两边的"{"需用空格隔离,同时使用";"表示命令结束。

[root@mghuee~chunlanyy testdir]# type {{ is a shell keyword

三.[]

"[]"主要用作条件判断,判断对象包括文件类型和赋值比较

[root@mghuee~chunlanyy testdir]# type [[ is a shell builtin

我们可以看到"["是一个内部命令,基本可认为等同于test命令

[root@mghuee~chunlanyy testdir]# [ 4 -lt 3 ] && echo yes || echo nono[root@mghuee~chunlanyy testdir]#  test 4 -lt 3  && echo yes || echo nono

常见的比较测试如下:

数字测试:-eq -ne -lt -le -gt -ge

文件测试:-r、-l、-w、-x、-f、-d、-s、-nt、-ot

字符串测试:=、!=、-n、-z、\>、\<

逻辑测试:-a、-o、!

数学运算:支持整数运算,但已被"((...))"取代

注意的几点:

1.数字比较只能用-lt这样的比较符,而不能使用"<"这样的比较符,即便是加了转义符的"\<"

[root@mghuee~chunlanyy testdir]# [ 1 > 2 ] && echo yes || echo noyes

很显然,"1>2"应该是错误的,但是显示"yes",实际上此处">"并非算术比较中的大于号,而为重定向输出,通过ls命令即可查看出当前目录下多出一个文件名为2的文件

[root@mghuee~chunlanyy testdir]# ll -ltotal 0-rw-r--r--. 1 root root 0 Jun 17 20:53 2

有人也会试想通过转义符进行数值比较

[root@mghuee~chunlanyy testdir]# [ 1 \> 2 ] && echo yes || echo nono

通过此比较符合我们的预期,但是"\>"在此并非进行我们日常中理解的大小数值比较

[root@mghuee~chunlanyy testdir]# [ a \> 2 ] && echo yes || echo noyes

此处比较是进行ASCII码值大小比较,同时此处只能支持单字符的大小比较

[root@mghuee~chunlanyy testdir]# [ 5 \> 20 ] && echo yes || echo noyes

2."[]"支持的逻辑运算符为-a、-o、!,此处-a、-o相当于是test命令的一个参数,不能使用&&、||

[root@mghuee~chunlanyy testdir]# [ 1 -lt  2 && 1 -lt 3 ] && echo yes || echo no-bash: [: missing `]'no

&&和||是强逻辑运算,会对命令进行拆分,在上述举例中已经拆分成"[ 1 -lt  2 " && "1 -lt 3 ]",故会显示没有配对的"["

在逻辑运算时,[ expre1 -a expre 2 ]与[[ expre1 && expre2 ]]并非完全一致,&&会进行逻辑短路操作,而-a并不会

[root@mghuee~chunlanyy testdir]# [ 1 -gt 3 -a 2 > test1.txt ] && echo yes || echo nono[root@mghuee~chunlanyy testdir]# lstest1.txt

并未进行逻辑短路操作,执行所有判断,即使"1 -gt 3"已经错误,依旧执行后续操作,虽然结果为no,但是还会生成test1.txt文件

[root@mghuee~chunlanyy testdir]# [[ 1 -gt 3 && 2 > test2.txt ]] && echo yes || echo nono[root@mghuee~chunlanyy testdir]# lstest1.txt

进行逻辑运算操作,在与命令中,"1 -gt 3"为false即不作后续判断,故无test2.txt的出现

3."[]"是命令,故在其中的变量引用或常量,需使用双引号或者单引号括起来,因为会出现单词分割(Word-Splitting)现象

[root@mghuee~chunlanyy testdir]# I=" 29";[ -f $I ] && echo yes || echo nono[root@mghuee~chunlanyy testdir]# I=" 29";[ -f "$I" ] && echo yes || echo noyes[root@mghuee~chunlanyy testdir]# ll -atotal 8drwxr-xr-x. 2 root root 4096 Jun 17 23:20 .drwxrwxrwt. 6 root root 4096 Jun 17 20:53 ..-rw-r--r--. 1 root root    0 Jun 17 23:17  29

在当前目录中存在一个文件名为" 29"的文件(29前面有空格),在[]中未对引用变量加入双引号时,[]内部执行判断为-f "29",因为当前目录中不存在文件名的"29"的文件,显示结果是No

四.(())

支持四则运算,等同于let功能

[root@mghuee~chunlanyy testdir]# let I=2+4;echo $I6[root@mghuee~chunlanyy testdir]# I=$((2+4));echo $I6

五.[[]]

"[["也是一个keyword,用于比较判断,基本支持"[]"中所有的判断比较符。

[root@mghuee~chunlanyy testdir]# type [[[[ is a shell keyword

"[["和"["的不同点:

1.逻辑运算符不一致,"[[]]"为"&&"、"||","[]"为"-a"、"-o"。"[[]]"支持逻辑短路,而"[]"不支持

2."[[]]"支持正则表达式的匹配。

3."[[]]"为一个keyword,同括号与表达式中间必须要有空格进行隔离

4."[[]]"中使用比较符时不能转义,同时不会出现Word-Splitting

[root@mghuee~chunlanyy testdir]# I=" 29";[[ -f $I ]] && echo yes || echo noyes[root@mghuee~chunlanyy testdir]# ll -atotal 8drwxr-xr-x. 2 root root 4096 Jun 17 23:20 .drwxrwxrwt. 6 root root 4096 Jun 17 20:53 ..-rw-r--r--. 1 root root    0 Jun 17 23:17  29

与上述"[]"的结果进行比较,很显然,在"[[]]"中并不会出现Word-Splitting

[root@mghuee~chunlanyy testdir]# [[ a > 1 ]] && echo yes || echo noyes[root@mghuee~chunlanyy testdir]# [[ a \> 1 ]] && echo yes || echo no-bash: conditional binary operator expected-bash: syntax error near `\>'

可以看出,使用转义后出现error

5.[[]]中"=="与"=~"的使用

引用《advanced bash-scripting guide》对两者的解释

== String comparison operator   <==字符串比较

=~ Regular Expression match operator  <==正则表达式匹配

但是在此也并非代表"=="在"[[]]"中不能实现正则表达式模式的匹配,也能实现部分的匹配

[root@mghuee~chunlanyy tmp]# [[ abc == a*b***c ]] && echo yes || echo noyes

但只能实现字符之间的匹配

[root@mghuee~chunlanyy tmp]# [[ `cat /etc/passwd` == ^root ]] && echo yes || echo nono[root@mghuee~chunlanyy tmp]# [[ `cat /etc/passwd` =~ ^root ]] && echo yes || echo noyes

而"=~"则能完整的按正则表达式去匹配

注意:在正则表达式模式匹配中,右边的匹配模式不能使用双引号,在bash 3.2版本之后已经明确说明在使用正则表达式时所匹配的模式不能加上双引号

[root@mghuee~chunlanyy tmp]# [[ `cat /tmp/123` =~ "^root" ]] && echo yes || echo noyes[root@mghuee~chunlanyy tmp]# cat 123"^root"[root@mghuee~chunlanyy tmp]# [[ `cat /tmp/123` =~ ^root ]] && echo yes || echo nono[root@mghuee~chunlanyy tmp]# cat 123"^root"

因为在"[[]]"不会出现Word-Splitting,加入后反而让上匹配模式变成了“"^root"”

小结:

1.进行算术运算时使用"let命令",或者"$(())""
2.进行文件存在或者字符是否为空时使用"[]"
3.逻辑运算符"&&"、"||"要在"[[]]"中使用,"-a"、"-o"在"[]"中使用
4.在"[[]]"中使用正则表达式进行匹配的时候所匹配模式不能使用双引号
5.数值大小比较时在"[]"中进行比较,要使用"-lt"、"-gt"这样的比较符,不能使用"<"、">"
6."[[]]"与"[]"两边最好都保持空格,"[[]]"是两边一定要有空格进行隔离
7.以上均为习惯使用方式,并非说明其它组合模式一定不可使用,但可避免出现一些让人费解的错误

转载于:https://blog.51cto.com/marility/1790628

bash中(),{},(()),[],[[]]的区别相关推荐

  1. read name 和 read 在 Bash 中的区别

    read 带一个参数和不带参数的区别是什么,我本以为仅仅是被赋值的变量的名字不同而已: $ read name 1 $ echo "$name" 1 $ read 1 $ echo ...

  2. Bash中的管道输出和捕获退出状态

    我想执行Bash中长时间运行的命令,都捕获它的退出状态,并且发球它的输出. 所以我这样做: command | tee out.txt ST=$? 问题在于变量ST捕获了tee而不是命令的退出状态. ...

  3. 如何检查Bash中是否设置了变量?

    我如何知道是否在Bash中设置了变量? 例如,如何检查用户是否将第一个参数赋予函数? function a {# if $1 is set ? } #1楼 检查是否设置了变量 var="&q ...

  4. shell变量加单引号sql_关于shell:在Bash中的命令中扩展变量的单引号

    我想从bash shell脚本中运行一个命令,该脚本在单引号和变量中包含单引号和一些其他命令. 如repo forall -c '....$variable'. 在这种格式中,对$进行转义,不展开变量 ...

  5. bash中 21 的解释

    1.首先,bash中0,1,2三个数字分别代表STDIN_FILENO.STDOUT_FILENO.STDERR_FILENO,即标准输入(一般是键盘),标准输出(一般是显示屏,准确的说是用户终端控制 ...

  6. Bash中的位置参数和特殊参数

    #Bash中的位置参数和特殊参数 #Bash中的位置参数是由0以外的一个或多个数字表示的参数. #位置参数是当Shell或Shell函数被引用时由Shell或Shell函数的参数赋值,并且可以使用Ba ...

  7. 中查询一个文件夹下文件数量_如何在 Bash 中使用循环 | Linux 中国

    使用循环和查找命令批量自动对多个文件进行一系列的操作.-- Seth Kenlon(作者) 人们希望学习批处理命令的一个普遍原因是要得到批处理强大的功能.如果你希望批量的对文件执行一些指令,构造一个可 ...

  8. anaconda prompt和cmd和powershell和anaconda powershell prompt和git bash有什么区别

    anaconda prompt和cmd和powershell和anaconda powershell prompt和git bash有什么区别? anaconda prompt和cmd和powersh ...

  9. bash中的字符串长度

    本文翻译自:Length of string in bash How do you get the length of a string stored in a variable and assign ...

最新文章

  1. 局域网瘫痪 傀儡主机的DDoS***
  2. 第九天:基础文件管理
  3. Kd-Tree算法原理和开源实现代码
  4. python使用pip安装本地包-Python之pip使用详解|附第三方库安装总结
  5. snmp v3 参数_snmp v3 配置
  6. 【遥感数字图像处理】实验:遥感图像分析方法大全(Erdas版)
  7. 某大厂外包员工在工作群抢新年红包,却被要求退回...
  8. kafka专题:kafka的Topic主题、Partition分区、消费组偏移量offset等基本概念详解
  9. java 判断一个词是不是成语_Java 判断字符串a和b是否互为旋转词
  10. VIPKID:笔试题(数组中和为0的一对数的数量,十进制转二进制中1的个数)
  11. [iOS]学习笔记3(动态性)
  12. 20165202 实验一 Java开发环境的熟悉
  13. 企业架构 | TOGAF架构能力框架
  14. SPI全双工模式下收发字节的理解
  15. serialization 序列化
  16. 手把手教你用移远M26/BC28的 MQTT协议 对接阿里云IoT平台
  17. k--最近邻算法(KNN)
  18. Seurat的normalization和scaling
  19. 如何查看网页上的图片体积大小或容量大小?
  20. 中国海洋大学2022CTF校赛

热门文章

  1. Pandas对象的层次化索引——【from_tuples()、from_arrays()、from_product()、swaplevel()、sort_index()、sort_values()】
  2. 网易校园招聘历年经典面试题汇总:C++研发岗
  3. leetcode448. 找到所有数组中消失的数字 天秀记录法
  4. 算法(21)-leetcode-剑指offer5
  5. 区块链上智能合约的讲解
  6. 2014年英语一阅读理解Text1
  7. finally语句与return语句的执行顺序
  8. FFMPEG中H.264的算法文档--整理自ffmpeg论坛等
  9. 狗窝里的小日子- 3 ...
  10. 发布在线文档【软件=业务+架构+流程+组织.pptx】