小U有一天想要使用shell脚本跑一段时间的脚本,写了下面一段shell语句,发现报错了,运行的时候变成了这样:

一开始以为是由于bash将0开头的数字作为8进制了,所以出现08,09这样的数字就会报错,之后发现是由于是用错了关键词和括号导致的。自此小U仿佛打开了新世界的大门,之前并没有系统了解过shell中的括号,经常出现混用的情况,今天我们就来总结一下shell中各种括号的使用方法和场景。

单小括号——( )

1) 命令组:

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

2) 初始化数组

其次小括号常被用于初始化数组。下图为初始化数组并对数组进行遍历输出。

3) 命令替换:

等同于 `cmd` ,shell扫描一遍命令行,发现了$(cmd)结构,便将$(cmd)中的cmd执行一次,得到其标准输出,再将此输出放到原来命令中。

双小括号——(( ))

1) 整数扩展:

这种扩展计算是整数型的计算,不支持浮点型。((exp))结构扩展并计算一个算术表达式的值,如果表达式的结果为0,那么返回的退出状态码为1,或者 是"假",而一个非零值的表达式所返回的退出状态码将为0,或者是"true"。若是逻辑判断,表达式exp为真则为1,假则为0。

2) 进制转化:

只要括号中的运算符、表达式符合C语言运算规则,都可用在$((exp))中,甚至是三目运算符。作不同进位(如二进制、八进制、十六进制)运算时,输出结果全都自动转化成了十进制。

3) 重定义变量值

可以对变量进行重定义,下图对变量a执行了++操作。

4) 算术运算比较

双括号中的变量可以不使用$符号前缀。括号内支持多个表达式用逗号分开。只要括号中的表达式符合C语言运算规则,比如可以直接使用for((i=0;i<5;i++)),其他写法包括for i in `seq 0 4` 或者for i in {0..4}。再如可以直接使用if (($i<5)), 如果不使用双括号, 则为if [ $i -lt 5 ]。注意浮点数是作为字符串处理。

单中括号——[ ]

1) 相当于test

“[”和test是等同的,if/test结构中的左中括号是调用test的命令标识,右中括号是关闭条件判断的。这个命令把它的参数作为比较表达式或者作为文件测试(判断文件是否存在是否可执行等),并且根据比较的结果来返回一个退出状态码。

2) 整数和字符串的比较

[ ]中可用的比较运算符只有==和!=,两者都是用于字符串比较的,不可用于整数比较,整数比较只能使用-eq,-gt这种形式。不能直接使用大于小于号。对于字符串比较可以使用转义形式,如果比较"ab"和"bc":[ ab \< bc ],结果为真,也就是返回状态为0。[ ]中的逻辑与和逻辑或使用-a 和-o 表示。

3) 字符范围

使用起来类似用作正则表达式的一部分,描述一个匹配的字符范围。

4) 在数组中括号用来引用数组中每个元素的编号

注意:$[ expr ]和$(( expr ))是一样的,都是进行数学运算的。支持+ - * / %(“加、减、乘、除、取模”)。但是注意,bash只能作整数运算,对于浮点数是当作字符串处理的。

双中括号——[[ ]]

1)部分shell中的内置命令

这是内置在部分shell中的一个命令,它就比刚才说的test强大的多了。支持字符串的模式匹配(使用=~操作符时甚至支持shell的正则表达式)。逻辑组合可以不使用test的-a,-o而使用&& ||。

2)模式匹配

字符串比较时可以把右边的作为一个模式,而不仅仅是一个字符串,比如[[ hello == hell? ]],结果为真。[[ ]] 中匹配字符串或通配符,不需要引号。

3)防止脚本中的许多逻辑错误

使用[[ ... ]]条件判断结构,而不是[ ... ],能够防止脚本中的许多逻辑错误。比如,&&、||、 操作符能够正常存在于[[ ]]条件判断结构中,但是如果出现在[ ]结构中的话,会报错。比如可以直接使用if [[ $a != 1 && $a != 2 ]], 如果不适用双括号, 则为if [ $a -ne 1] && [ $a != 2 ]或者if [ $a -ne 1 -a $a != 2 ]。

注意:使用[]和[[]]的时候不要吝啬空格,每一项两边都要有空格,[[ 1 == 2 ]]的结果为“假”,但[[ 1==2 ]]的结果为“真”!

大括号——{ }

1)大括号拓展

通配(globbing)对大括号中的文件名做扩展。在大括号中,不允许有空白,除非这个空白被引用或转义。第一种:对大括号中的以逗号分割的文件列表进行拓展。如 touch {a,b}.txt 结果为a.txt b.txt。第二种:对大括号中以点点(..)分割的顺序文件列表起拓展作用,如:touch {a..d}.txt 结果为a.txt b.txt c.txt d.txt

2)代码块(又被称为内部组)

这个结构事实上创建了一个匿名函数,与小括号中的命令不同,大括号内的命令不会新开一个子shell运行,即脚本余下部分仍可使用括号内变量。括号内的命令间用分号隔开,最后一个也必须有分号。{ }的第一个命令和左括号之间必须要有一个空格。下图中可以看到小括号括起来的部分只在对应子shell中作用,参数并没有传出来。

3)字符串提取和替换

类似python中的substr和replace方法。下图测试了几重常用的字符提取替换方法。

4)模匹配替换结构

  • ${variable}用于变量替换。一般情况下,$var 与${var} 并没有什么不一样,但是用 ${ } 会比较精确的界定变量名称的范围。

  • 假设我们定义了一个变量为:file=/dir1/dir2/dir3/my.file.txt,我们可以用 ${ } 分别替换获得不同的值:

${file*/}:拿掉第一条 / 及其左边的字符串:dir1/dir2/dir3/my.file.txt${file*/}:拿掉最后一条 / 及其左边的字符串:my.file.txt${file*.}:拿掉第一个 .  及其左边的字符串:file.txt${file*.}:拿掉最后一个 .  及其左边的字符串:txt${file%/*}:拿掉最后条 / 及其右边的字符串:/dir1/dir2/dir3${file%%/*}:拿掉第一条 / 及其右边的字符串:(空值)${file%.*}:拿掉最后一个 .  及其右边的字符串:/dir1/dir2/dir3/my.file${file%%.*}:拿掉第一个 .  及其右边的字符串:/dir1/dir2/dir3/my

总结

  • (…) 是命令列表。这些命令在单独的子过程中执行,因此在括号内执行的任何重定向,赋值等在括号外均无效。{ … }大括号类似于括号,但是在当前shell中执行,语法有所不同。

  • $(…)是命令的替换:括号内有一个命令,并且命令的输出用作命令行的一部分,等价于反引号。

  • ((…))双括号将算术指令(对整数的计算)括起来,其语法类似于其他编程语言。此语法主要用于赋值和条件句中。

  • $((…))是算术表达式,该语法扩展为表达式计算后的整数值。

  • [ … ]单括号包围条件表达式。条件表达式主要建立在运算符上。不能直接用>

  • [[ … ]]双括号是部分shell中条件表达式的替代形式,具有一些附加功能,在对字符串进行比较判断的时候最好使用这个。

  • 带有前导美元符号的${VAR}是参数扩展,扩展为变量的值,并可能进行额外的转换。

  • 比较的时候慎用shell中的字符串比较,如果要使用的话使用bash中的[[ ]]更符合一般的编程习惯。

  • 如果要使用选的日期,时间等,尽量将其转化为yyyymmdd形式或者秒数,通过整数的比较和计算之后再转回需要的形式,这样可以减少错误的发生。

往期推荐:

【UI分享】游戏交互提升技巧,想看吗?

【RD分享】正确处理CSRF校验

【UE分享】玩家吐槽“猪队友”时,到底在吐槽什么?

【UI分享】远程武器准星设计方法论

【US分享】如何实现shell脚本的单例运行

判断正则 shell_【US分享】Shell中的括号相关推荐

  1. shell中的括号(小括号,中括号,大括号/花括号)

    一.小括号,园括号() 1.单小括号 () ①命令组.括号中的命令将会新开一个子shell顺序执行,所以括号中的变量不能够被脚本余下的部分使用.括号中多个命令之间用分号隔开,最后一个命令可以没有分号, ...

  2. shell中各种括号的作用详解()、(())、[]、[[]]、{}(推荐)

    一.小括号,圆括号() 1.单小括号 () ①命令组.括号中的命令将会新开一个子shell顺序执行,所以括号中的变量不能够被脚本余下的部分使用.括号中多个命令之间用分号隔开,最后一个命令可以没有分号, ...

  3. shell中的括号(小括号,大括号/花括号)

    在这里我想说的是几种shell里的小括号,大括号结构和有括号的变量,命令的用法,如下: 1.${var}  2.$(cmd)  3.()和{}  4.${var:-string},${var:+str ...

  4. shell中的括号(小括号,大括号/花括号)的使用方法

    在这里我想说的是几种shell里的小括号,大括号结构和有括号的变量,命令的用法,如下: 1.${var}  2.$(cmd)  3.()和{}  4.${var:-string},${var:+str ...

  5. shell 中的括号(小括号,花括号)

    链接:http://my.oschina.net/xiangxw/blog/11407 在这里我想说的是几种shell里的小括号,大括号结构和有括号的变量,命令的用法,如下: 1.${var}  2. ...

  6. shell中各种括号()、(())、[]、[[]]、{}的作用和区别

    $()和 ` ` 在 bash shell 中,$( ) 与` ` (反引号) 都可用做命令替换用. 例如   version=$(uname -r)和version=`uname -r`都可以是ve ...

  7. 判断正则 shell_年薪百万之路--第七十八天 Linux基础 shell

    一. 基础知识部分: · 变量知识概念 1)常规变量: 临时定义方式: 在脚本中或命令行中设置 oldboy=123 永久定义方式: 在特殊系统变量文件中设置 /etc/profile /etc/ba ...

  8. shell中各种括号的作用

    小括号里是命令大括号是变量值   一.小括号,圆括号() 1.单小括号 () ①命令组.括号中的命令将会新开一个子shell顺序执行,所以括号中的变量不能够被脚本余下的部分使用.括号中多个命令之间用分 ...

  9. 一文读懂 Shell 中各种括号的作用

    [欢迎关注微信公众号:厦门微思网络] 微思网络(官网):https://www.xmws.cn/ 一.小括号,圆括号() 1.单小括号 () ①命令组.括号中的命令将会新开一个子shell顺序执行,所 ...

最新文章

  1. Mixing Milk(USACO)
  2. android标题栏添加按钮_改善Android布局性能
  3. pandas改变dataframe的列的顺序、改变数据列的排列次序
  4. mysql在建站起什么作用_数据库操作对比:Sql Server与MYSQL相比有哪些建站优势?...
  5. 计算机默认存储格式,office2007默认保存文件格式的修改方法
  6. Linux下main函数带参数问题和atoi函数详解
  7. go 打印 %v %+v %#v 的区别
  8. AIO+BIO+NIO+同步+异步+阻塞+非阻塞
  9. 使用数据库恢复专家,修复数据库
  10. typescript 博客_如何使用Typescript自动化博客发布过程
  11. es6删除数组某项_es6删除数组元素或者对象元素的方法介绍(代码)
  12. JSP和FreeMarker的比较
  13. 下 文库 试读_数字资源专题导览 | 科学文库简介
  14. 你见过最奇葩的人和事是什么?
  15. 网管必读-常用网络命令
  16. 兰资环单招计算机基础主要考什么,高职单招考试范围单招一般都考什么科目
  17. word转pdf或者打印后题注编号变成大写
  18. 余世维+金正昆+陈安之+曾仕强+张锦贵等资料集
  19. FBEC2020专访 | 贾瑶琪:Substrate可以在Web3.0中找出更多有意思的创新应用
  20. 关于苹果的iOS cercertificate的创建问题

热门文章

  1. 调用另一个python文件中的代码
  2. Jupyter安装r内核
  3. Bitmap和YUV的转换
  4. 了解在HCI部署VDI的优势
  5. mysql的dml语句_Mysql基础入门-SQL_DML语句
  6. mySql的case when用法
  7. linux网络速度不稳定,关于Linux下上网速度慢的问题
  8. php 函数导航,PHP经典分页导航函数
  9. 三阶矩阵的lu分解详细步骤_数学 - 线性代数导论 - #4 矩阵分解之LU分解的意义、步骤和成立条件...
  10. 由于存储区是只读的,存储区已满,或者存储区没有正确打开,所以导致失败