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

一.()

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

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

二.{}

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

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

xyz

[root@mghuee~chunlanyy testdir]# I=;{ echo $I;I=xyz;echo $I; };echo $I

xyz
xyz

从例子中可以看得,"()"中的赋值只能影响到自身子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]# [  -lt  ] && echo yes || echo no
no
[root@mghuee~chunlanyy testdir]# test -lt && echo yes || echo no
no

常见的比较测试如下:

数字测试:-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]# [  >  ] && echo yes || echo no
yes

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

[root@mghuee~chunlanyy testdir]# ll -l
total
-rw-r--r--. root root Jun :

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

[root@mghuee~chunlanyy testdir]# [  \>  ] && echo yes || echo no
no

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

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

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

[root@mghuee~chunlanyy testdir]# [  \>  ] && echo yes || echo no
yes

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

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

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

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

[root@mghuee~chunlanyy testdir]# [  -gt  -a  > test1.txt ] && echo yes || echo no
no
[root@mghuee~chunlanyy testdir]# ls
test1.txt
并未进行逻辑短路操作,执行所有判断,即使"1 -gt 3"已经错误,依旧执行后续操作,虽然结果为no,但是还会生成test1.txt文件
[root@mghuee~chunlanyy testdir]# [[  -gt  &&  > test2.txt ]] && echo yes || echo no
no
[root@mghuee~chunlanyy testdir]# ls
test1.txt

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

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

[root@mghuee~chunlanyy testdir]# I="";[ -f $I ] && echo yes || echo no
no
[root@mghuee~chunlanyy testdir]# I="";[ -f "$I" ] && echo yes || echo no
yes
[root@mghuee~chunlanyy testdir]# ll -a
total
drwxr-xr-x. root root Jun : .
drwxrwxrwt. root root Jun : ..
-rw-r--r--. root root Jun :

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

四.(())

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

[root@mghuee~chunlanyy testdir]# let I=+;echo $I

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

五.[[]]

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

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

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

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

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

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

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

[root@mghuee~chunlanyy testdir]# I="";[[ -f $I ]] && echo yes || echo no
yes
[root@mghuee~chunlanyy testdir]# ll -a
total
drwxr-xr-x. root root Jun : .
drwxrwxrwt. root root Jun : ..
-rw-r--r--. root root Jun :

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

[root@mghuee~chunlanyy testdir]# [[ a >  ]] && echo yes || echo no
yes
[root@mghuee~chunlanyy testdir]# [[ a \> ]] && 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 no
yes

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

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

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

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

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

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

小结:

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

bash中(),{},(()),[],[[]]的区别的更多相关文章

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

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

  2. bash中的set, env, export unset的区别

    参考这篇文章很好 参考这篇文章2 -------------------------- == set显示的是当前shell的变量, 不同的shell, 它的私有变量是不同的 env是显示用户的变量, ...

  3. Bash中的任务(job)管理

    本来不准备写这篇博客的,因为任务管理(job管理)非常非常常用,以至于觉得根本没有必要去写这样一个东西.但想了下,还是记录一下吧,也许有人会用到呢. 不知你是否碰到过这样的情况,当你兴致勃勃的打开VI ...

  4. shell脚本中的[]/[[]]区别

    转自:http://www.cnblogs.com/include/archive/2011/12/09/2307905.html 引用: http://www.51testing.com/?uid- ...

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

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

  6. bash中 2>&1 & 的解释

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

  7. bash 中 () {} [] [[]] (()) 的解释

    bash 中 () {} [] [[]] (()) 的解释 来源  https://www.cnblogs.com/fhefh/archive/2011/04/16/2017895.html bash ...

  8. 『忘了再学』Shell基础 — 9、Bash中的特殊符号(一)

    目录 1.双单引号 2.双引号 3.$符号 4.反引号 5.$()符号 6.#符号 7.\符号 1.双单引号 '':单引号.在单引号中所有的特殊符号,如$和"`"(反引号)都没有特 ...

  9. 『忘了再学』Shell基础 — 10、Bash中的特殊符号(二)

    提示:本篇文章接上一篇文章,主要说说()小括号和{}大括号的区别与使用. 8.()小括号 ():用于一串命令执行时,()中的命令会在子Shell中运行.(和下面大括号一起说明) 9.{}大括号 {}: ...

随机推荐

  1. 编写自己的Nmap(NSE)脚本

    编写自己的Nmap脚本 一.介绍 在上一篇文章Nmap脚本引擎原理中我们介绍了基本的NSE知识,这篇文章介绍如何基于Nmap框架编写简单的NSE脚本文件,下一篇文章,Nmap脚本文件分析(AMQP协议 ...

  2. 使用CSS3动画实现绚丽的照片墙效果

    临近毕业了,一大波毕业照又要来袭了!如何使用CSS3属性制作出自己的网页版照片墙呢? 闲话少说,先来看看效果图 效果要求: 1,照片要求有一定的白色边框. 2,照片都要有一定的倾斜角度. 3,鼠标移动 ...

  3. javaScript的一些奇妙动画

         今天我给大家讲一下JavaScript中的显示隐藏.淡入淡出的效果 显示与隐藏动画效果 show()方法: show()方法会动态地改变当前元素的高度.宽度和不透明度,最终显示当前元素,此时 ...

  4. 还原SQL SERVER系统库

    还原SQL SERVER系统库 共需还原三个系统库,还原顺序:master>msdb>model 还原master (1).数据库配置管理器->数据库服务属性->启动参数-&g ...

  5. 在centos6.7中lnmp环境下安装swoole插件和pthreads插件

    1.首先在安装lnmp集成包之前,解压lnmp1.3-full.tar.gz,进入到lnmp1.3-full/include/目录下; 2.输入 vi php.sh;编辑php.sh文档.博主安的是p ...

  6. @JsonIgnoreProperties忽略转换到json的属性

    bean转换到json忽略指定属性 @JsonIgnoreProperties(value={"attrName"})

  7. php通过curl扩展进行模拟登录(含验证码)

    以下为本人工作中遇到的需要做的事情,之前也没怎么用过curl,查了好多资料,才稍微弄明白一点:本文所有内容只是自己平日工作的记录,仅供大家参考:<?php/*** 模拟登录*/header(&q ...

  8. FFT/NTT 多项式学习笔记

    FFT(快速傅立叶变换)和NTT(快速数论变换)看上去很高端,真正搞懂了就很simple了辣. 首先给出多项式的一些定义(初中数学内容): 形如Σaixi的式子就是多项式! 多项式中每个单项式叫做多项 ...

  9. 【请求之密】payload和formData有什么不同?

    最近做项目的时候,在通过post请求向服务端发送数据的时候,请求失败了.错误信息如下: 返回的400(bad request)错误,说明客户端这边发送的请求是有问题的. 和通过jquery中的ajax ...

  10. axis1.4开发webservice客户端(快速入门)-基于jdk1.4

    写在前面: 对于客户端,服务端开发好了以后,客户端只需要调用就可以了.这里我们讲的是,根据服务的访问地址,来生成客户端所需要用到的代码(听说有几种调用方式,但是用到最常见的就是stub方式,貌似我说的 ...