Skip to content

Shell-3

引号

  • 单引号 '' :字符全部视为普通字符,不会转义

  • 双引号 "" :字符部分视为普通字符,变量**会被转义**

  • 反引号 :字符**视为命令**,执行后替换将结果替换原字符

  • $(命令):执行命令后将结果输出

Example

num=10
echo 'Hello, I am Boii\n $num'      # Output:Hello, I am Boii\n $num

echo "Hello, I am Boii\n $num"      # Output:Hello, I am Boii\n 10

echo 'Today is' `date`               # Output:Today is 2021年 06月 17日 星期四 10:19:56 CST

echo "Here is $(pwd)"                # Output:Here is /home/boii

条件表达式

表达式 实例
[ expression ] [ 1 -eq 1 ]
[[ expression ]] [[ 1 -eq 1 ]]
test expression test 1 -eq 1 ,等同于[ 1 -eq 1 ]

整数比较符

比较符 描述 示例
-eq,equal 等于 [ 1 -eq 1 ]为 true
-ne,not equal 不等于 [ 1 -ne 1 ]为 false
-gt,greater than 大于 [ 2 -gt 1 ]为 true
-lt,lesser than 小于 [ 2 -lt 1 ]为 false
-ge,greater or equal 大于或等于 [ 2 -ge 1 ]为 true
-le,lesser or equal 小于或等于 [ 2 -le 1 ]为 false

字符串比较符

运算符 描述 示例
== 等于 [ "a" == "a" ]为 true
!= 不等于 [ "a" != "a" ]为 false
> 大于,判断字符串时根据ASCII 码表顺序,不常用 []表达式中:[ 2 > 1 ]为 true
[[]]表达式中:[[ 2 > 1 ]]为 true
(())表达式中:(( 3 > 2 ))为 true
< 小于,判断字符串时根据ASCII 码表顺序,不常用 [ 2 < 1 ]为 false
[[ 2 < 1 ]]为 false
(( 3 < 2 ))为 false
>= 大于等于 (())表达式中:(( 3 >= 2 ))为 true
<= 小于等于 (())表达式中:(( 3 <= 2 ))为 false
-n 字符串长度不等于 0 为真 VAR1=1
VAR2=""
[ -n "$VAR1" ]为 true
[ -n "$VAR2" ]为 false
-z 字符串长度等于 0 为真 VAR1=1
VAR2=""
[ -z "$VAR1" ]为 false
[ -z "$VAR2" ]为 true
str 字符串存在为真 VAR1=1
VAR2=""
[ $VAR1 ]为 true
[ $VAR2 ]为 false

在使用 -z-n 判断字符串长度时,变量要加双引号。

Example

a='Hello'
[ -z $a ] && echo 'yes' || echo 'no'    # yes
[ -n $a ] && echo 'yes' || echo 'no'    # yes

需要加上双引号才能正常判断

eg:

a='Hello'
[ -z "$a" ] && echo 'yes' || echo 'no'  # yes
[ -n "$a" ] && echo 'yes' || echo 'no'  # no

如果使用双中括号就不需要加双引号

Example

a='Hello'
[[ -z $a ]] && echo 'yes' || echo 'no'  # yes
[[ -n $a ]] && echo 'yes' || echo 'no'  # no

布尔运算符和逻辑运算符

运算符 描述 示例
! 非关系,条件结果取反 [ ! 1 -eq 2 ] 为 true
-a 与关系,在[]表达式中使用 [ 1 -eq 1 -a 2 -eq 2 ] 为 true
-o 或关系,在[]表达式中使用 [ 1 -eq 1 -o 2 -eq 1 ] 为 true
&& 逻辑与
[[]](()) 表达式中或判断表达式是否为真时使用
[[ 1 -eq 1 && 2 -eq 2 ]] 为 true

(( 1 == 1 && 2 == 2 )) 为 true

[ 1 -eq 1 ] && echo yes如果 && 前面表达式为 true 则执行后面的
|| 逻辑或
[[]](()) 表达式中或判断表达式是否为真时使用
[[ 1 -eq 1 || 2 -eq 1 ]] 为 true

(( 1 == 1 || 2 == 2 )) 为 true

[ 1 -eq 2 ] || echo yes 如果 || 前面的表达式为 false 则执行后面打印 yes

运算表达式

整数运算符

运算符 描述
+ 假发
- 减法
* 乘法
/ 除法
% 取余

运算表达式

运算表达式 示例 备注
$(()) $((1+1)) 可以在括号中赋值给变量
$[] $[1+1] 不可以在括号中赋值给变量

Example

a=$((10+20))
echo $a              # 30

echo $((5+5))       # 10

((b=15+15))
echo $b              # 30

x=18
y=28
echo $(( x+y ))    # 46

# ----------------------------------------------

echo $[40+40]       # 80

echo $[ 40+40 ]     # 80

c=10
d=15
echo $[ c+d ]       # 25

# ----------------------------------------------
# 错误写法
[a=40+40]
[ a=40+40 ]
$[a=40+40]
$[ a=40+40 ]

以上两个运算表达式均 不支持浮点运算

  • $(()) 还有另外一个用途:三目运算

    Example

    a=10
    b=20
    echo $((a>b ? 100 : -1))    # -1    ,条件为假,返回-1
    echo $((a<b ? 100 : -1))    # 100   ,条件为真,返回100
    
  • 也可以简化,使用默认值

    Example

    a=10
    b=20
    echo $((a>b))   # 0,相当于 $((a>b ? 1 : 0))
    echo $((a<b))   # 1,相当于 $((a<b ? 1 : 0))
    

    注意,不支持返回字符串

其他运算工具

  • let
  • expr
  • bc

let

赋值并运算

Example

let v=(1+2)*3
echo $v     # 6

x=10
y=20
let x++; echo $x    # 11
let y--; echo $y    # 19

let x+=2; echo $x   # 13
let y-=3; echo $y   # 16

bc

Shell 不支持浮点数比较,可以借助 bc 命令来完成

Example

echo "1.2 < 2" | bc     # 1
echo "1.2 > 2" | bc     # 0
echo "1.2 == 2" | bc    # 0
echo "1.2 != 2" | bc    # 1

expr

expr 可以对字符串操作

  1. 获取字符串长度

    expr length 字符串
    

    Example

    expr length "Hello"     # 5
    
  2. 截取字符串

    expr substr 字符串 起始下标 结束下标
    

    Example

    expr substr "Hello, Boii" 4 8   # lo, B
    

    这里下标从 1 开始,且左包含+右包含。

  3. 获取字符在字符串中的位置

    expr index 字符串 字符
    

    Example

    expr index "Hello, Boii" 'l'    # 3
    expr index "Hello, Boii" o      # 5
    

    这里只返回字符在字符串中最先出现的位置

  4. 获取从头匹配长度

    expr match 字符串 模式串
    

    Example

    expr match "Hello, Boii" He         # 2
    expr match "Hello, Boii" Hello      # 5
    expr match "Hello, Boii" ello       # 0
    

复合命令

使用复合命令,可以将多条指令组合在一起执行

{} 形式

{} 括起来的命令在本 shell 内执行,括号内的命令改变本 shell 的变量值及工作目录。

注意

{ 后需有一个空格

} 前需有一个分号 ;

Example

> { a=`pwd`; echo $a; }     # 在本 shell 执行
/home/boii

> { cd /bin; a=`pwd`; echo $a; }    # a的值此时被修改
/bin

>pwd    # 本 shell 会受影响
/bin

() 形式

() 括起来的命令在子 shell 内执行,括号内的命令不会改变本 shell 的变量值及工作目录。

Tip

( 后无需空格

) 前无需空格

Example

> (cd /var/www/html; a=`pwd`; echo $a)  # 在子 shell 执行
/var/www/html

> pwd   # 本 shell 不受影响
/home/boii

括号用途总结

  1. 圆括号

    • ()
      • 用途1:在运算中,先计算小括号里的内容
      • 用途2:数组
      • 用途3:正则匹配分组
      • 用途4:在子 Shell 内执行命令
    • (())
      • 用途1:表达式,不支持 -eq、-a、-o 这类运算符,支持 <=、==、&&、|| 这类比较符。
      • 用途2:C语言风格的 for(()) 表达式
    • $():执行 Shell 命令,与反撇号等效
    • $(())
      • 用途1:简单算术运算
      • 用途2:三目运算 $((expression?num:num))
  2. 方括号

    • []:条件表达式,不支持逻辑判断符 && 、||
    • [[]]:条件表达式,不支持 -a、-o、>=、<=,支持 -eq、>、< 这类比较符。可以不用双引号,更通用。
    • $[]:简单算术运算,不支持逻辑比较。
  3. 花括号

    • {}:对逗号 , 和点点 .. 起作用
      • touch {a,b}:创建 a 和 b 两个文件
      • touch {1..4}:创建 1、2、3、4 四个文件
      • 用途2:在本 Shell 内执行命令
    • ${}
      • 用途1:引用变量
      • 用途2:字符串处理