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 - 程序在运行时会存在三种变量
- 局部变量
在脚本中定义,当前脚本中有效。 - 环境变量
所有脚本都能访问。 - shell变量
shell程序设置的特殊变量。
- 局部变量
$
在引用定义过的变量时使用 如果未定义,则为控 再次赋值时,不使用$
如:
Name="xiaofei"echo $Nameecho ${Name}Name="zheng"echo $Name
特殊的shell变量
| 变量 | 含义 |
|---|---|
| $0 | 当前脚本的文件名 |
| $n | 传递给脚本或函数的参数。n是一个数字,表示第几个参数。$1表示第一参数 |
| $# | 传递给脚本或函数的参数个数。 |
| $* | 传递给脚本或函数的所有参数。 |
| $@ | 传递给脚本或函数的所有参数 |
| $? | 上一函数执行的返回状态 |
| $$ | 当前脚本的进程ID |
- $@ 和 $*的区别
在被””包裹时,
@会将参数分开输出。
特殊字符
\ 转义字符
| 转义字符 | 含义 |
|---|---|
| \\ | 反斜线 |
| \t | 缩进 |
| \n | 换行 |
| \f | 换页 |
| \r | 回车 |
| \a | 报警 |
- 输出时使用转移字符时需要配合 -e,否则会原样输出 如:
echo -e "value is $a \n"
``命令替换
被``包裹的命令先执行,进行暂时存放。如:date命令获取当前时间。
Date = `date`echo $Date
变量替换
根据变量的值进行替换
| 形式 | 说明 |
|---|---|
| ${var} | 变量原值 |
| ${var:-word} | 如果变量为空或已经被删除,则返回word |
| ${var:=word} | 如果变量为空或已经被删除,则返回word,并将var赋值为word |
| ${var:?message} | 如果变量为空或已经被删除,将message进行输出,并停止脚本 |
| ${var:+word} | 如果变量var被定义,那么返回word,但不改变var的值 |
运算符
算术运算符
- expr
表达式和运算符之间要有空格, 完整的表达式要被``包裹 乘号前需要加转义字符”\“ 如:
expr 2 \* 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 |
如:a=10b=20if[a -ge b]thenecho "a is equal b"elseecho "a is not equal b"fi结果: a is not equal b
布尔运算符
| 运算符 | 说明 | 举例 |
|---|---|---|
| ! | 非 | [! false] ,返回true |
| -o | 或 | [true -o false] ,返回true |
| -a | 与 | [true -a ture] ,返回true |
字符串运算符
| 运算符 | 说明 | 举例( |
|---|---|---|
| = | 判断是否相等 | [ $a = $b ],返回false |
| != | 判断是否不相等 | [ $a != $b ],返回true |
| -z | 判断字符串长度是否为0 | [ -z $b],返回true |
| -n | 判断字符串长度是否不为0 | [ -n $a],返回true |
| str | 判断字符串是否为空 | [ $b ],返回false |
示例:#!/bin/basha="b"b="c"#b=""unset $aecho $bif [ $a ]thenecho $aecho $becho "a\`s length is not zero"elseecho "a\`s length is zero"fi结果:ba`s length is not zero
文件测试运算符
| 运算符 | 说明 |
|---|---|
| -d | 判断文件是否为目录(文件夹),如果是返回true |
| -f | 判断文件是否为普通文件 |
| -r | 判断文件是否可读 |
| -w | 判断文件是否可写 |
| -x | 判断文件是否可执行 |
| -s | 判断文件是否为空,文件大小是否大于0 |
| -e | 判断文件是否存在 |
#!/bin/bashfilename="/usr/zheng/text.sh"if [ -r $filename ]thencat /usr/zheng/text.shelseecho "filename can not read"fi
字符串
单引号和双引号的区别
- 单引号
- 单引号的中的任何字符都会原样输出
- 单引号中的变量是无效的
- 单引号中不能出现单引号(使用转义字符也不行)
- 双引号
- 双引号中可以有变量
- 可以出现转义字符
- 可以出现单引号
例:str='123'name="hh$str"echo -e "hello,"$name"!\n"echo "hello,"$name"!\n"echo "hello,\"$name\"!"输出:hello,hh123!\nhello,hh123!hello,"hh123"!
获取字符串长度
- 使用#
例:str="adbc"echo "${#str}"输出:4
截取字符串
例:String="i love you"echo ${String:1:4}输出:lov
查找字符串
- 查找最靠前的字符位置
例:str="zhanggongzi"echo `expr index "$str" og`输出:5
数组
- bash支持一维数组,不支持多维数组
- 对数组的大小没有限定
- 下标由0开始
- 使用()来表示数组
- 用空格隔开
@/*输出所有元素
获取数组长度
例:#!/bin/basharray=("name""+""hello")echo ${array[@]}#array[0]="hello"str=${arrry[0]}array[5]=${array[3]}echo ${array[0]}echo ${array[5]}echo ${#array[*]}输出:name + helloname4
echo
printf
条件判断
- if…fi
- if…else …fi
- if…elif…else…fi
注意事项:
判断条件使用[]包含 表达式和[]之间需要由空格隔开
read
读取命令行输入内容,赋值给变量
如:read NAMEecho "I LOVE YOU , $NAME!"
输出当前时间
echo date +%F
定义空数组
arr=()
整数自增
tmp=01.let tmp++2.let tmp+=13.tmp=`expr $a + 1`4.$(($tmp+1))
for循环
for j in ${arr[@]}doif [ $j == Tools ]; thenlet tmp++fidone
if判断
if [ $tmp == 2 ];thenecho $dateelseecho ""fi
脚本命令返回结果转数组
定义数组,为其将返回结果保存在()中,()中是脚本命令。
数组输出时使用 {}包裹,如echo ${arr[0]},不适用{}包裹会出现输出问题。
#! /bin/bashlineNum=`virsh list --all | grep -v "Id\|--" | awk '{print $2}' | wc -l`arr=(`virsh list --all | grep -v "Id\|--" | awk '{print $2}'`)for ((i=0; i<$lineNum; i++))doecho ${arr[$i]}done
for循环遍历
循环体使用do和done包裹
可以使用in
for j in ${arr[@]}doif [ $j == Tools ]; thenlet tmp++fidone
也可以类似java,注意括号
#注意使用两个括号for ((i=0; i<$lineNum; i++))doecho ${arr[$i]}done
脚本后台执行
输入输出
0:标准输入
1:标准输出
2:错误输出
/dev/null:linux中的黑洞文件,添加到该文件的数据都被删除。
nohup:后台执行,不占用当前窗口,用在命令开头
&:后台执行,用在命令结尾。
nohup /tmp/test.sh > /test.txt 2>&1 &;
nohup /tmp/test.sh > /dev/nul &;
