shell

#!

!是一个约定的标记,告知系统用什么解释器来执行,即使用哪种shell。

shell 分类 sh、ash、csh、bash等。

!/bin/bash — 意思是使用/bin目录下的bash执行【bash也是个脚本】

  • 也可以在执行时自定义解释器,如:/bin/sh test.sh这种情况按照外部定义的解释器执行,不按照脚本内部定义的执行

./

脚本使用./执行,或者全路径执行 ./的意思是在当前目录下寻找脚本。 vim 其实也是脚本,这种脚本之所以不需要使用./,是因为在path里配置了路径 全路径是到目标目录下去寻找脚本后执行 脚本执行需要添加执行权限 chmod +x a.sh

#

号为注释作用

没有多行注释

  • 多行注释的方法

因为shell为解释型语言 所以可以将要注释的代码用{}括起来作为一个方法,但是不进行调用 该代码块就不会执行,和注释起到了相同作用。

变量

shell支持自定义变量 变量、等号、值之间不能有空格 首个字符必须为字母 不能有空格 支持下划线 不能使用标点符号 不能使用bash中的关键字 如: Name="xiaofei"

  • readonly 只读
    readonly修饰的变量修改时会报错 readonly name
  • unset 删除变量
    unset 可以删除变量,只读变量不能被删除,删除后再次使用值为空
    unset name
  • 程序在运行时会存在三种变量
    1. 局部变量
      在脚本中定义,当前脚本中有效。
    2. 环境变量
      所有脚本都能访问。
    3. shell变量
      shell程序设置的特殊变量。

$

在引用定义过的变量时使用 如果未定义,则为控 再次赋值时,不使用$

如:

  1. Name="xiaofei"
  2. echo $Name
  3. echo ${Name}
  4. Name="zheng"
  5. echo $Name

特殊的shell变量

变量 含义
$0 当前脚本的文件名
$n 传递给脚本或函数的参数。n是一个数字,表示第几个参数。$1表示第一参数
$# 传递给脚本或函数的参数个数。
$* 传递给脚本或函数的所有参数。
$@ 传递给脚本或函数的所有参数
$? 上一函数执行的返回状态
$$ 当前脚本的进程ID
  • $@ 和 $*的区别

在被””包裹时,shell - 图1@会将参数分开输出。

特殊字符

\ 转义字符

转义字符 含义
\\ 反斜线
\t 缩进
\n 换行
\f 换页
\r 回车
\a 报警
  • 输出时使用转移字符时需要配合 -e,否则会原样输出 如:echo -e "value is $a \n"

``命令替换

被``包裹的命令先执行,进行暂时存放。如:date命令获取当前时间。

  1. Date = `date`
  2. echo $Date

变量替换

根据变量的值进行替换

形式 说明
${var} 变量原值
${var:-word} 如果变量为空或已经被删除,则返回word
${var:=word} 如果变量为空或已经被删除,则返回word,并将var赋值为word
${var:?message} 如果变量为空或已经被删除,将message进行输出,并停止脚本
${var:+word} 如果变量var被定义,那么返回word,但不改变var的值

运算符

算术运算符

  • expr

    表达式和运算符之间要有空格, 完整的表达式要被``包裹 乘号前需要加转义字符”\“ 如:

  1. expr 2 \* 2

条件运算符

  1. > 条件表达式要放在方括号中
  2. 只支持数字,不支持字符串
运算符 说明 举例(a=10 ,b=20)
-eq 判断是否相等,相等true [ $a -eq $b ] ,返回false
-ne 判断是否相等,不相等true [ $a -ne $b ] ,返回true
-gt 左边是否大于右边,是返回true [ $a -gt $b ] ,返回false
-lt 左边是否小于右边,是返回true [ $a -lt $b ] ,返回true
-ge 左边是否大于等于右边,是返回true [ $a -ge $b ] ,返回false
-le 左边是否小于等于右边,是返回true [ $a -le $b ] ,返回true
  1. 如:
  2. a=10
  3. b=20
  4. if[a -ge b]
  5. then
  6. echo "a is equal b"
  7. else
  8. echo "a is not equal b"
  9. fi
  10. 结果: a is not equal b

布尔运算符

运算符 说明 举例
[! false] ,返回true
-o [true -o false] ,返回true
-a [true -a ture] ,返回true

字符串运算符

运算符 说明 举例(shell - 图2b=””)
= 判断是否相等 [ $a = $b ],返回false
!= 判断是否不相等 [ $a != $b ],返回true
-z 判断字符串长度是否为0 [ -z $b],返回true
-n 判断字符串长度是否不为0 [ -n $a],返回true
str 判断字符串是否为空 [ $b ],返回false
  1. 示例:
  2. #!/bin/bash
  3. a="b"
  4. b="c"
  5. #b=""
  6. unset $a
  7. echo $b
  8. if [ $a ]
  9. then
  10. echo $a
  11. echo $b
  12. echo "a\`s length is not zero"
  13. else
  14. echo "a\`s length is zero"
  15. fi
  16. 结果:
  17. b
  18. a`s length is not zero

文件测试运算符

运算符 说明
-d 判断文件是否为目录(文件夹),如果是返回true
-f 判断文件是否为普通文件
-r 判断文件是否可读
-w 判断文件是否可写
-x 判断文件是否可执行
-s 判断文件是否为空,文件大小是否大于0
-e 判断文件是否存在
  1. #!/bin/bash
  2. filename="/usr/zheng/text.sh"
  3. if [ -r $filename ]
  4. then
  5. cat /usr/zheng/text.sh
  6. else
  7. echo "filename can not read"
  8. fi

字符串

单引号和双引号的区别

  • 单引号
    • 单引号的中的任何字符都会原样输出
    • 单引号中的变量是无效的
    • 单引号中不能出现单引号(使用转义字符也不行)
  • 双引号
    • 双引号中可以有变量
    • 可以出现转义字符
    • 可以出现单引号
  1. 例:
  2. str='123'
  3. name="hh$str"
  4. echo -e "hello,"$name"!\n"
  5. echo "hello,"$name"!\n"
  6. echo "hello,\"$name\"!"
  7. 输出:
  8. hello,hh123!\n
  9. hello,hh123!
  10. hello,"hh123"!

获取字符串长度

  • 使用#
  1. 例:
  2. str="adbc"
  3. echo "${#str}"
  4. 输出:
  5. 4

截取字符串

  1. 例:
  2. String="i love you"
  3. echo ${String:1:4}
  4. 输出:
  5. lov

查找字符串

  • 查找最靠前的字符位置
  1. 例:
  2. str="zhanggongzi"
  3. echo `expr index "$str" og`
  4. 输出:5

数组

  • bash支持一维数组,不支持多维数组
  • 对数组的大小没有限定
  • 下标由0开始
  • 使用()来表示数组
  • 用空格隔开

@/*输出所有元素

获取数组长度

  1. 例:
  2. #!/bin/bash
  3. array=("name"
  4. "+"
  5. "hello"
  6. )
  7. echo ${array[@]}
  8. #array[0]="hello"
  9. str=${arrry[0]}
  10. array[5]=${array[3]}
  11. echo ${array[0]}
  12. echo ${array[5]}
  13. echo ${#array[*]}
  14. 输出:
  15. name + hello
  16. name
  17. 4

echo

printf

条件判断

  • if…fi
  • if…else …fi
  • if…elif…else…fi

注意事项:

判断条件使用[]包含 表达式和[]之间需要由空格隔开

read

读取命令行输入内容,赋值给变量

  1. 如:
  2. read NAME
  3. echo "I LOVE YOU , $NAME!"

输出当前时间

  1. echo date +%F

定义空数组

  1. arr=()

整数自增

  1. tmp=0
  2. 1.let tmp++
  3. 2.let tmp+=1
  4. 3.tmp=`expr $a + 1`
  5. 4.$(($tmp+1))

for循环

  1. for j in ${arr[@]}
  2. do
  3. if [ $j == Tools ]; then
  4. let tmp++
  5. fi
  6. done

if判断

  1. if [ $tmp == 2 ];then
  2. echo $date
  3. else
  4. echo ""
  5. fi

-z:判断字符串长度是否为0

脚本命令返回结果转数组

定义数组,为其将返回结果保存在()中,()中是脚本命令。

数组输出时使用 {}包裹,如echo ${arr[0]},不适用{}包裹会出现输出问题。

  1. #! /bin/bash
  2. lineNum=`virsh list --all | grep -v "Id\|--" | awk '{print $2}' | wc -l`
  3. arr=(`virsh list --all | grep -v "Id\|--" | awk '{print $2}'`)
  4. for ((i=0; i<$lineNum; i++))
  5. do
  6. echo ${arr[$i]}
  7. done

for循环遍历

循环体使用do和done包裹

可以使用in

  1. for j in ${arr[@]}
  2. do
  3. if [ $j == Tools ]; then
  4. let tmp++
  5. fi
  6. done

也可以类似java,注意括号

  1. #注意使用两个括号
  2. for ((i=0; i<$lineNum; i++))
  3. do
  4. echo ${arr[$i]}
  5. done

脚本后台执行

输入输出
0:标准输入
1:标准输出
2:错误输出

/dev/null:linux中的黑洞文件,添加到该文件的数据都被删除。

nohup:后台执行,不占用当前窗口,用在命令开头
&:后台执行,用在命令结尾。

nohup /tmp/test.sh > /test.txt 2>&1 &;
nohup /tmp/test.sh > /dev/nul &;