文章目录

  • 一、`()`
    • 1、命令组
    • 2、命令替换
    • 3、初始化数组
  • 二、`(())`
    • 1、C语言规则运算
    • 2、重定义变量值
    • 3、算术比较
  • 三、`[]`
    • 1、条件判断
    • 2、字符范围
    • 3、数组下标
  • 四、`[[]]`
    • 1、条件判断
    • 2、返回状态码
  • 五、`{}`
    • 1、字符扩展
    • 2、代码块
    • 3、特殊替换结构
    • 4、模式匹配截断
    • 5、长度截断

一、()

1、命令组

连接多个命令组,用;隔开,最后一个命令后;可加可不加。括号中的命令会新开一个子shell顺序执行,所以里面的操作对括号外主进程无关。

a=0
(a=1;b=2;echo $a) # 子进程内输出a为1
echo $a # 主进程,输出a为0

2、命令替换

格式为 $(command),相当于 `command`。shell遇到此格式,会先执行 command 命令,得到标准输出,再将此输出放回到原来命令。

SCRIPTPATH=$(dirname $0)  # sh脚本的相对目录

3、初始化数组

Shell 数组用括号来表示,元素用"空格"符号分割开。

array=(a b c)
echo ${array[1]} # 输出b

二、(())

1、C语言规则运算

表达式 $((exp)),其中exp只要符合C语言规则的运算符即可,包括加减乘除、+=<=>=等。

进行不同进位(如二进制、八进制、十六进制)运算时,输出结果会全都自动转化成十进制。

echo $((2*2+(1-2))) # 输出3
a=1
echo $((a++)) # 输出2,且从此之后a=2
echo $((2#10+4)) # 输出6,在10前面的2#表示这是个二进制
echo $((a<2)) # 输出1。如果为假,则输出0。

2、重定义变量值

((exp))中可以对变量进行定义或重新赋值,且之后脚本全部有效(不是像()那样只在子进程有效)。

a=1
((a=2))
echo $a # 输出2

3、算术比较

((exp))中可以进行算术比较(不能进行字符串比较),双括号中的变量可以省略$符号前缀,当然也可以带着。

a=1
((a==1)) && echo "true" # 输出 true
(($a==1)) && echo "true" # 输出 true

三、[]

1、条件判断

[] 本质上是 test 语句,[是调用test的命令标识,]是关闭条件判断,如:

a="abc"
if [ -n "$a" ]; then echo "true"; fi # 输出true,注意[]内-n或者-z时字符串两边必须加上双引号
if test -n "$a"; then echo "true"; fi # 输出true,注意test内-n或者-z时字符串两边必须加上双引号

2、字符范围

用作正则表达式的一部分,描述一个匹配的字符范围,如删除一个字符串中的所有数字:

echo "ap1p23le" | tr -d "[0-9]" # 输出 apple
echo [a-b].txt # 输出:a.txt b.txt,前提是两个文件都存在。
# 但是如果当前路径只存在a.txt或b.txt,则只会输出存在的文件。
# 如果两个文件均不存在,则输出固定字符串:[a-b].txt

3、数组下标

在一个array后,作为引用数组元素的下标,如

a=(1 2 3)
echo ${a[0]} # 输出:1
echo ${a[*]} # 输出:1 2 3

四、[[]]

1、条件判断

使用[[]]条件判断结构,与[]有以下区别:

  • 本质上,[]test是命令,而[[]]是关键字,所以重定向等字符在[]中会被认为成重定向,而在[[]]中是比较符号的意思。
  • &&||<> 操作符能够正常存在于[[]]条件判断结构中,但是如果出现在[]结构中的话,会报错。比如可以直接使用if [[ $a != 1 && $a != 2 ]], 如果不使用双括号, 则为if [ $a != 1] && [ $a != 2 ]或者if [ $a != 1 -a $a != 2 ]
  • [[]]支持字符串的模式匹配,[]不支持。使用===进行字符串比较,等号右边的可以作为一个模式,比如[[ "hello" == hell? ]]为真。模式匹配不能加引号,否则会作为固定字符串,如[[ "hello" == "hell?" ]]为假。
  • [[]]支持算术扩展,而[]不支持。如if [[ 1+2 -eq 3 ]],而if [ 1+2 -eq 3 ]则会报错。

2、返回状态码

本质上,bash把[[]]中的表达式看作一个单独的元素,并返回一个退出状态码。

比如:

[[ 1 -gt 0 ]]
echo $? # 输出0
[[ 1 -gt 2 ]]
echo $? # 输出1

可以看到,如果[[]]内的表达式为真,则返回退出码0,这也是其他所有命令执行正常时所返回的退出码。

因此,如果用[[]]作为if的判断条件,道理是和判断一个命令或函数是否顺利执行是一样的。

五、{}

1、字符扩展

{}可以作为通配符进行扩展,有两种用法:

  • echo {a,b}.txt 输出a.txt b.txt。与echo [a-b].txt区别在于,后者只输出存在的文件名,而前者不管是不是存在此文件,永远都会输出a.txt b.txt,因为{}的字符扩展和是不是文件名没有关系。
  • echo {a..c}.txt输出a.txt b.txt c.txt

这两种扩展也可以用于循环:

$ for i in {0,2};do echo $i;done
0
2
$ for i in {0..2};do echo $i;done
0
1
2

2、代码块

又被称为内部组,格式为{ cmd1;cmd2;},这个结构事实上创建了一个匿名函数 。

{}()都可以执行一连串命令,区别如下:

  • ()会新开一个子进程,括号内命令与括号外无关。{}内的命令不会新开一个子进程运行,即脚本余下部分仍可使用括号内变量。
  • 两者括号内的命令间都要用;隔开,但()最后一个命令的分号可有可无,但{}最后一个也必须有分号。
  • {}的第一个命令和左括号{之间必须要有一个空格(右括号}无此要求),而()两个括号的空格均可有可无。

3、特殊替换结构

有4种特殊的替换结构:${var:-string},${var:+string},${var:=string},${var:?string}

(1)${var:-string}表示若变量var不为空,则等于var的值,否则等于string的值。

比如:

a=''
b="bbb"
echo ${a:-foo} # 输出:foo
echo ${a:-"foo"} # 输出:foo
echo ${a:-$b} # 输出:bbb

(2)${var:=string}的替换规则与${var:-string}相同,不过多了一步操作:若var为空时,还会把string的值赋给var

比如:

a=''
b="bbb"
echo ${a:=$b} # 输出:bbb
echo $a # 输出:bbb

(3)${var:+string}的替换规则和上面的相反,表示若变量var不为空,则等于string的值,否则等于var的值(即空值)。
比如:

a=""
b="bbb"
echo ${a:+"foo"} # 输出为空
echo ${b:+"foo"} # 输出:foo

(4)${var:?string}表示若变量var不为空,则等于var的值,否则把string输出到标准错误中,并从脚本中退出。

我们可利用此特性来检查是否设置了变量的值,比如一个脚本test.sh内容如下:

#!/bin/bash
a=""
b="bbb"
echo ${a:?"warn:string is null"}
echo ${b:?"warn:string is null"}
echo "done"

然后在命令行中执行命令:

$ sh test.sh > out.log 2> err.log # 标准输出至out.log,标准错误输出至err.log
$ cat out.log
aaa
$ cat err.log
test.sh: line 5: b: warn:string is null

可以看到,out.log中没有done,因此脚本执行到Line 5的错误就提前退出了。

4、模式匹配截断

有4种模式:${var%pattern},${var%%pattern},${var#pattern},${var##pattern}

(1)${var%pattern}表示看var是否以模式pattern结尾,如果是,就把var中的内容去掉右边最短的匹配模式。

(2)${var%%pattern}表示看var是否以模式pattern结尾,如果是,就把var中的内容去掉右边最长的匹配模式。

(3)${var#pattern}表示看var是否以模式pattern开始,如果是,就把var中的内容去掉左边最短的匹配模式。

(4)${var##pattern}表示看var是否以模式pattern开始,如果是,就把var中的内容去掉左边最长的匹配模式。

比如:

a="apple"
echo ${a%"le"} # 去掉右边固定"le",输出:app
echo ${a%p*} # 去掉右边最短匹配,输出:ap
echo ${a%%p*} # 去掉右边最长匹配,输出:a
echo ${a#*p} # 去掉左边最短匹配,输出:ple
echo ${a##*p} # 去掉左边最长匹配,输出:le

5、长度截断

有2种模式:${var:num},${var:num1:num2}

(1)${var:num}表示提取var中第num个字符到末尾的所有字符。若num为正数,从左边0处开始;若num为负数,从右边开始提取字串,但必须使用在冒号后面加空格或一个数字或整个num加上括号,如${var: -2}${var:1-3}${var:(-2)}

(2)${var:num1:num2}表示从var中第num1个位置开始提取长度为num2的子串。num1从0开始。

比如:

a="apple"
echo ${a:2} # 去掉前2个,输出:ple
echo ${a: -2} # 保留后2个,输出:le
echo ${a:1:3} # 保留从1开始的3个字符,输出:ppl

shell中各种括号(),[],(()),[[]],{}等的作用大全及示例相关推荐

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

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

  2. 判断正则 shell_【US分享】Shell中的括号

    小U有一天想要使用shell脚本跑一段时间的脚本,写了下面一段shell语句,发现报错了,运行的时候变成了这样: 一开始以为是由于bash将0开头的数字作为8进制了,所以出现08,09这样的数字就会报 ...

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

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

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

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

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

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

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

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

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

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

  8. shell中各种括号的作用

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

  9. Linux Shell脚本攻略:shell中各种括号()、(())、[]、[[]]、{}的作用

    技巧小结: 字符串比较用双中括号[[ ]]:算数比较用单中括号[ ]--左右留空格 算数运算用双小括号(( )) :shell命令及输出用小括号( )--左右不留空格 快速替换用花括号{ }--左右留 ...

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

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

最新文章

  1. 在Linux里设置环境变量的方法(export PATH)
  2. Navicat 连接MySQL数据库 报错2059 - authentication plugin 'caching_sha2_password'的解决办法...
  3. 你在听音乐的时候能否感受到背后有“寒意“?
  4. matlab中的图像,MATLAB中图像的基本操作
  5. ARM64的启动过程之(四):打开MMU
  6. html分页器的实现原理,Django之分页器
  7. 自动驾驶——标注工具(js+electron)的开发笔记(基于Create-React-App)
  8. 蓝牙要抢ZigBee的地盘?低功耗广域网络笑了
  9. 华为设备VRRP+MSTP冗余负载均衡实现
  10. linux librtmp 编译,在linux系统下安装python librtmp包的实现方法
  11. 西电Pintos操作系统课程设计 实验三
  12. PyCharm常用配置和常用插件
  13. 电机与拖动:异步交流电动机改变电压,转子电阻及频率的机械特性曲线(Matlab实现方法)
  14. html5制作旋转正方体,html5—旋转立方体
  15. Mysql数据表和表数据复制
  16. H3C的l2tp报错
  17. 【智能硬件】初识RKNN
  18. includes的用法
  19. java与seo_学习seo和学习java哪个更好
  20. 毕业设计 STM32平衡车设计与实现

热门文章

  1. OpenCV边缘检测算法
  2. Python.translate(table).maketrans(‘str1‘,‘str2‘)字符串翻译
  3. android短视频列表自动播放,手把手教你实现视频列表滚动自动播放-短视频列表滚动播放实战...
  4. 【用法总结】C++中常用的大小写转换(4种常用方法)
  5. 论文解读:Unprocessing Images for Learned Raw Denoising
  6. 京东商城API 商品详情接口
  7. 罗永浩2014 一个理想主义者的创业故事Ⅳ 演讲稿实录
  8. ALSA子系统(十三)------snd_pcm_hw_refine硬件参数重定义
  9. CodeForces比赛规则
  10. java中的StringBuffer类