转自:https://www.cnblogs.com/HKUI/p/6423918.html

查看脚本语法是否有错误:
bash -n modify_suffix.sh
跟踪执行
sh -x modify_suffix.sh aaa

  1. 1.${var}
  2. 2.$(cmd)
  3. 3.()和{}
  4. 4.${var:-string},${var:+string},${var:=string},${var:?string}
  5. 5.$((exp))
  6. 6.$(var%pattern),$(var%%pattern),$(var#pattern),$(var##pattern)

1.Shell中变量的原形:${var}

但当你要显示变量值加随意的字符(我这里用_AA)时,就会出错

这时应该用变量的原形:${var},即是加一个大括号来限定变量名称的范围

  1. [root@bogon sh]# aa='ajax'
  2. [root@bogon sh]# echo $aa
  3. ajax
  4. [root@bogon sh]# echo $aa_AA
  5.  
  6. [root@bogon sh]# echo ${aa}_AA
  7. ajax_AA

批量修改一个目录里文件名

  1. [root@bogon ~]# cat modify_suffix.sh
  2. #!/bin/bash
  3. dst_path=$1
  4. for file in `ls $dst_path`
  5. do
  6. if [ -d $1/$file ]
  7. then echo `$0 $1/$file`
  8. elif [ -f $1/$file ]
  9. then mv $1/$file $1/${file}._mod
  10. else
  11. echo $1/${file} is unknow file type
  12. fi
  13.  
  14. done;
  15. ./modify_suffix.sh ./f
  16. ./f 下的所有文件文件名添加了.mod
  1. [root@bogon ~]# file="modify_suffix.sh.tar.gz"
  2. [root@bogon ~]# echo "${file%%.*}"
  3. modify_suffix
  4. [root@bogon ~]# echo "${file%.*}"
  5. modify_suffix.sh.tar
  6. [root@bogon ~]# echo "${file#*.}"
  7. sh.tar.gz
  8. [root@bogon ~]# echo "${file##*.}"
  9. gz

2.$(cmd)

  1. [root@bogon t]# ls
  2. 1.txt 2.txt
  3. [root@bogon t]# echo $(ls)
  4. 1.txt 2.txt
  1. echo $(ls) 执行过程
  2. shell扫描一遍命令行,发现了$(cmd)结构,便将$(cmd)中的cmd执行一次,得到其标准输出,
  3. 再将此输出放到原来命令 echo $(ls)中的 $(ls)位置,即替换了$(ls),再执行echo命令
  4. 如下:
  5. echo $(ls)被替换成了echo 1.txt 2.txt
  6. 这里要注意的是$(cmd)中的命令的错误输出是不会被替换的,替换的只是标准输出
  1. [root@bogon t]# var=$(cat 3.txt)
  2. cat: 3.txt: 没有那个文件或目录
  3. [root@bogon t]# echo $var
  4.  
  5. $var显然是空的

3、一串的命令执行()和{}
()和{}都是对一串的命令进行执行,但有所区别:
相同点:
()和{}都是把一串的命令放在括号里面,并且命令之间用;号隔开
不同点
()只是对一串命令重新开一个子shell进行执行,{}对一串命令在当前shell执行
()最后一个命令可以不用分号,{}最后一个命令要用分号
()里的第一个命令和左边括号不必有空格,{}的第一个命令和左括号之间必须要有一个空格
()和{}中括号里面的某个命令的重定向只影响该命令,但括号外的重定向则影响到括号里的所有命令

  1. [root@bogon t]# var=test
  2. [root@bogon t]# echo $var
  3. test
  4. [root@bogon t]# (var=notest;echo $var)
  5. notest
  6. [root@bogon t]# echo $var
  7. test
  8. [root@bogon t]# { var=notest;echo $var;}
  9. notest
  10. [root@bogon t]# echo $var
  11. notest
  12. [root@bogon t]#

在{}中 第一个命令和{之间必须有空格,结束必须有;
{}中的修改了$var的值 说明在当前shell执行

  1. [root@bogon t]# { var1=test1;var2=test2;echo $var1>a;echo $var2;}
  2. test2
  3. [root@bogon t]# cat a
  4. test1
  5. [root@bogon t]# { var1=test1;var2=test2;echo $var1;echo $var2;}>a
  6. [root@bogon t]# cat a
  7. test1
  8. test2
  9. 脚本实例
  10. (
  11. echo "1"
  12. echo "2"
  13. ) | awk '{print NR,$0}'

4.几种特殊的替换结构:

  1. ${var:-string},${var:+string},${var:=string},${var:?string}

(1)

  1. ${var:-string} ${var:=string}

若变量var为空或者未定义,则用在命令行中用string来替换${var:-string}
否则变量var不为空时,则用变量var的值来替换${var:-string}

  1. [root@bogon ~]# echo $a
  2.  
  3. [root@bogon ~]# echo ${a:-bcc}
  4. bcc
  5. [root@bogon ~]# echo $a
  6.  
  7. [root@bogon ~]# a=ajax
  8. [root@bogon ~]# echo ${a:-bcc}
  9. ajax
  10. [root@bogon ~]# unset a
  11. [root@bogon ~]# echo $a
  12.  
  13. [root@bogon ~]# echo ${a:=bbc}
  14. bbc
  15. [root@bogon ~]# echo $a
  16. bbc

发现

  1. ${var:-string}和${var:=string}

比较 后者发现$var为空时,把string赋值给了var
后者是一种赋值默认值的常见做法

(2) ${var:+string}
规则和上面的完全相反
即只有当var不是空的时候才替换成string,若var为空时则不替换或者说是替换成变量var的值,即空值

  1. [root@bogon ~]# a=ajax
  2. [root@bogon ~]# echo $a
  3. ajax
  4. [root@bogon ~]# echo ${a:+bbc}
  5. bbc
  6. [root@bogon ~]# echo $a
  7. ajax
  8. [root@bogon ~]# unset a
  9. [root@bogon ~]# echo $a
  10.  
  11. [root@bogon ~]# echo ${a:+bbc}
  12.  
  13. [root@bogon ~]#

(3). ${var:?string}
替换规则:若变量var不为空,则用变量var的值来替换${var:?string}
若变量var为空,则把string输出到标准错误中,并从脚本中退出。
可利用此特性来检查是否设置了变量的值

  1. [root@bogon ~]# echo $a
  2.  
  3. [root@bogon ~]# echo ${a:?bbc}
  4. -bash: a: bbc
  5. [root@bogon ~]# a=ajax
  6. [root@bogon ~]# echo ${a:?bbc}
  7. ajax
  8. [root@bogon ~]# a=ajax
  9. [root@bogon ~]# echo ${a:-`date`}
  10. ajax
  11. [root@bogon ~]# unset a
  12. [root@bogon ~]# echo ${a:-`date`}
  13. 2017 02 21 星期二 10:13:46 CST
  14. [root@bogon ~]# echo ${a:-$(date)}
  15. 2017 02 21 星期二 10:13:59 CST
  16. [root@bogon ~]# b=bbc
  17. [root@bogon ~]# echo ${a:-$b}
  18. bbc

5.$((exp)) POSIX标准的扩展计算
这种计算是符合C语言的运算符,也就是说只要符合C的运算符都可用在$((exp)),包括三目运算符
注意:这种扩展计算是整数型的计算,不支持浮点型和字符串等
若是逻辑判断,表达式exp为真则为1,假则为0

  1. [root@bogon ~]# echo $(3+2)
  2. -bash: 3+2: 未找到命令
  3.  
  4. [root@bogon ~]# echo $((3+2))
  5. 5
  6. [root@bogon ~]# echo $((3.5+2))
  7. -bash: 3.5+2: 语法错误: 无效的算术运算符 (错误符号是 ".5+2"
  8. [root@bogon ~]# echo $((3>2))
  9. 1
  10. [root@bogon ~]# echo $((3>2?'a':'b'))
  11. -bash: 3>2?'a':'b': 语法错误: 期待操作数 (错误符号是 "'a':'b'"
  12. [root@bogon ~]# echo $((3>2?a:b))
  13. 0
  14. [root@bogon ~]# echo $((a=3+2))
  15. 5
  16. [root@bogon ~]# echo $((a++))
  17. 5
  18. [root@bogon ~]# echo $a
  19. 6

6.四种模式匹配替换结构:

  1. ${var%pattern}
  2. ${var%%pattern}
  3. ${var#pattern}
  4. ${var##pattern}
  5.  
  6. ${var%pattern},${var%%pattern} 从右边开始匹配
  7. ${var#pattern},${var##pattern} 从左边开始匹配
  8. ${var%pattern} ,${var#pattern} 表示最短匹配,匹配到就停止,非贪婪
  9. ${var%%pattern},${var##pattern} 是最长匹配

只有在pattern中使用了通配符才能有最长最短的匹配,否则没有最 长最短匹配之分
结构中的pattern支持通配符
* 表示零个或多个任意字符
?表示零个或一个任意字符
[...]表示匹配中括号里面的字符
[!...]表示不匹配中括号里面的字符

  1. [root@bogon ~]# f=a.tar.gz
  2. [root@bogon ~]# echo ${f##*.}
  3. gz
  4. [root@bogon ~]# echo ${f%%.*}
  5. a
  6. [root@bogon ~]# var=abcdccbbdaa
  7. [root@bogon ~]# echo ${var%%d*}
  8. abc
  9. [root@bogon ~]# echo ${var%d*}
  10. abcdccbb
  11. [root@bogon ~]# echo ${var#*d}
  12. ccbbdaa
  13. [root@bogon ~]# echo ${var##*d}
  14. aa
  15. #发现输出的内容是var去掉pattern的那部分字符串的值
  1. 一、小括号,圆括号()
  2.  
  3. 1、单小括号 ()
  4.  
  5. ①命令组。括号中的命令将会新开一个子shell顺序执行,所以括号中的变量不能够被脚本余下的部分使用。括号中多个命令之间用分号隔开,最后一个命令可以没有分号,各命令和括号之间不必有空格。
  6.  
  7. ②命令替换。等同于`cmd`shell扫描一遍命令行,发现了$(cmd)结构,便将$(cmd)中的cmd执行一次,得到其标准输出,再将此输出放到原来命令。有些shell不支持,如tcsh
  8.  
  9. ③用于初始化数组。如:array=(a b c d)
  10.  
  11. 2、双小括号 (( ))
  12.  
  13. ①整数扩展。这种扩展计算是整数型的计算,不支持浮点型。((exp))结构扩展并计算一个算术表达式的值,如果表达式的结果为0,那么返回的退出状态码为1,或者 "假",而一个非零值的表达式所返回的退出状态码将为0,或者是"true"。若是逻辑判断,表达式exp为真则为1,假则为0
  14.  
  15. ②只要括号中的运算符、表达式符合C语言运算规则,都可用在$((exp))中,甚至是三目运算符。作不同进位(如二进制、八进制、十六进制)运算时,输出结果全都自动转化成了十进制。如:echo $((16#5f)) 结果为95 (16进位转十进制)
  16.  
  17. ③单纯用 (( )) 也可重定义变量值,比如 a=5; ((a++)) 可将 $a 重定义为6
  18.  
  19. ④常用于算术运算比较,双括号中的变量可以不使用$符号前缀。括号内支持多个表达式用逗号分开。 只要括号中的表达式符合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 ]。
  20.  
  21. 二、中括号,方括号[]
  22.  
  23. 1、单中括号 []
  24.  
  25. bash 的内部命令,[和test是等同的。如果我们不用绝对路径指明,通常我们用的都是bash自带的命令。if/test结构中的左中括号是调用test的命令标识,右中括号是关闭条件判断的。这个命令把它的参数作为比较表达式或者作为文件测试,并且根据比较的结果来返回一个退出状态码。if/test结构中并不是必须右中括号,但是新版的Bash中要求必须这样。
  26.  
  27. Test和[]中可用的比较运算符只有==和!=,两者都是用于字符串比较的,不可用于整数比较,整数比较只能使用-eq,-gt这种形式。无论是字符串比较还是整数比较都不支持大于号小于号。如果实在想用,对于字符串比较可以使用转义形式,如果比较"ab""bc":[ ab \< bc ],结果为真,也就是返回状态为0。[ ]中的逻辑与和逻辑或使用-a 和-o 表示。
  28.  
  29. ③字符范围。用作正则表达式的一部分,描述一个匹配的字符范围。作为test用途的中括号内不能使用正则。
  30.  
  31. ④在一个array 结构的上下文中,中括号用来引用数组中每个元素的编号。
  32.  
  33. 2、双中括号[[ ]]
  34.  
  35. ①[[是 bash 程序语言的关键字。并不是一个命令,[[ ]] 结构比[ ]结构更加通用。在[[和]]之间所有的字符都不会发生文件名扩展或者单词分割,但是会发生参数扩展和命令替换。
  36.  
  37. ②支持字符串的模式匹配,使用=~操作符时甚至支持shell的正则表达式。字符串比较时可以把右边的作为一个模式,而不仅仅是一个字符串,比如[[ hello == hell? ]],结果为真。[[ ]] 中匹配字符串或通配符,不需要引号。
  38.  
  39. ③使用[[ ... ]]条件判断结构,而不是[ ... ],能够防止脚本中的许多逻辑错误。比如,&&、||、<和> 操作符能够正常存在于[[ ]]条件判断结构中,但是如果出现在[ ]结构中的话,会报错。比如可以直接使用if [[ $a != 1 && $a != 2 ]], 如果不适用双括号, 则为if [ $a -ne 1] && [ $a != 2 ]或者if [ $a -ne 1 -a $a != 2 ]。
  40.  
  41. bash把双中括号中的表达式看作一个单独的元素,并返回一个退出状态码。
  42. 例子:

  

shell中的(),{}几种语法用法的更多相关文章

  1. Shell中的(),{}几种语法用法-单独总结

    shell中的(),{}几种语法用法 查看脚本语法是否有错误: bash -n modify_suffix.sh 跟踪执行 sh -x modify_suffix.sh aaa 1. ${var} 2 ...

  2. [记录]Shell中的getopts和getopt用法

    Shell中的getopts和getopt用法 1.getopts getopts(shell内置命令)不能直接处理长的选项(如:--prefix=/home等),getopts有两个参数,第一个参数 ...

  3. Linux shell中&,&&,|,||的用法

    前言 在玩dvwa的命令注入漏洞的时候,遇到了没有预料到的错误,执行 ping 127.0.0.1 & echo "<?php phpinfo(); ?>" & ...

  4. 不可不看!CSS3中三十一种选择器用法

    原文 The 30 CSS Selectors you Must Memorize 由 Jeffrey Way 发表于 2012 年 6 月,介绍了 30 种最常用的 CSS 选择器用法,多加了一种, ...

  5. shell中echo基础及高级用法详解-渐入佳境

    --作者:飞翔的小胖猪 --创建时间:2021年2月19日 1.1 基础用法 echo命令用来输出文本,在shell脚本中用来输出提示信息用的比较多. 单引号:原样输出所有的内容,不用转义就能输出特殊 ...

  6. shell中的四种模式匹配

    POSIX为shell为进行模式匹配提供了四种参数替换结构(老版本的shell可能不支持),每种结构有两个参数:变量名(或变量号)及模式. 第一种模式:    ${variable%pattern}, ...

  7. 推荐掌握Linux shell中这7种运算命令

    #常见的算术运算符号 .+.-:加减 .*./.%:乘.除.取余 .**:幂运算 .++.--:增加记减少 .!.&&.||:取反,并且,或 .<,<=,>,=> ...

  8. Shell中read的选项及用法

    1. Read的一些选项 Read可以带有-a, -d, -e, -n, -p, -r, -t, 和 -s八个选项. -a :将内容读入到数值中 echo -n "Input muliple ...

  9. 发现linux shell中$0,$?,$!等的特殊用法

    记录下linux shell下的特殊用法及参数的说明 变量说明: $$ Shell本身的PID(ProcessID) $! Shell最后运行的后台Process的PID $? 最后运行的命令的结束代 ...

随机推荐

  1. OpenGL ES 光照模型之——漫反射光(RenderMonkey测试,地球日出效果)

    概述及目录(版权所有,请勿转载 http://www.cnblogs.com/feng-sc) 本文在上一篇(OpenGL ES 光照模型之——环境光照(RenderMonkey测试))环境光基础上, ...

  2. Configure Pi as simulation hardware for Simulink

    1. Only version not older than R2013 supports Raspberry Pi. First, download support package in Matla ...

  3. ASP.NET MVC 4 中Razor 视图中JS无法调试

    解决方法 1.首先检查IE中这2个属性是否勾选了. 2.选择IE浏览器进行调试,调试方法有2种     A:采用debugger;的方法,如下图所示: 这时不用调试断点就会在debugger位置中命中 ...

  4. Nodejs书写爬虫工具

    看了几天的nodejs,的确是好用,全当是练手了,就写了一个爬虫工具. 爬虫思路都是一致的,先抓取页面数据,然后分析页面,获取到所需要的数据,最后获得这些数据,是写入到硬盘,还是显示到网页,自己看着办 ...

  5. python 实现过滤出tomcat日志中含有ERROR 或Exception 的行并保存在另一个文件

    遍历多个tomcat日志文件,找出含有ERROR 和Exception 的日志,并把该行日志输出到另一个文件中:(这里为了体现python模块导入的知识,所有建立了多个文件夹和模块) 项目结构: co ...

  6. 浏览器报ScriptResource.axd异常

    新拷贝的一份管理后台代码,部署在另一台服务器上时,查看浏览器调控制台,发现有几个红色报错.这些错误导致网站的部分功能无法使用. 主要错误有: 1.“Sys”未定义 2.asp.net ajax 客户端 ...

  7. javascript 对象克隆

    浅克隆 先看代码: /** * 浅克隆 克隆传入对象,只克隆一层 * @param {any} source */ function shallowClone(source) { var tiaget ...

  8. Visual Studio在Win10中以管理员方式运行

    在Win10中运行VS不是默认以管理员程序运行的,需要手动设置 第一步:将VS快捷方式设置为以管理员身份运行 第二部 在C:\Program Files\Microsoft Visual Studio ...

  9. string的函数的学习

    1.string类型的构造函数和对象的定义 string s3 : 把string s2 拷贝的 s3 string s4 : 把数组首地址或者字符串首地址strArr 从0开始截取到第n个字母 st ...

  10. java之JIT(Just in time)

    Java程序最初是通过解释器进行解释执行的,当虚拟机发现某个方法或代码块运行的特别频繁时,会把这些代码认定为“热点代码”(Hot Spot Code).为了提高热点代码的执行效率,在运行时,虚拟机会把 ...