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 $Name
echo ${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=10
b=20
if[a -ge b]
then
echo "a is equal b"
else
echo "a is not equal b"
fi
结果: a is not equal b
布尔运算符
运算符 | 说明 | 举例 |
---|---|---|
! | 非 | [! false] ,返回true |
-o | 或 | [true -o false] ,返回true |
-a | 与 | [true -a ture] ,返回true |
字符串运算符
运算符 | 说明 | 举例(b=””) |
---|---|---|
= | 判断是否相等 | [ $a = $b ],返回false |
!= | 判断是否不相等 | [ $a != $b ],返回true |
-z | 判断字符串长度是否为0 | [ -z $b],返回true |
-n | 判断字符串长度是否不为0 | [ -n $a],返回true |
str | 判断字符串是否为空 | [ $b ],返回false |
示例:
#!/bin/bash
a="b"
b="c"
#b=""
unset $a
echo $b
if [ $a ]
then
echo $a
echo $b
echo "a\`s length is not zero"
else
echo "a\`s length is zero"
fi
结果:
b
a`s length is not zero
文件测试运算符
运算符 | 说明 |
---|---|
-d | 判断文件是否为目录(文件夹),如果是返回true |
-f | 判断文件是否为普通文件 |
-r | 判断文件是否可读 |
-w | 判断文件是否可写 |
-x | 判断文件是否可执行 |
-s | 判断文件是否为空,文件大小是否大于0 |
-e | 判断文件是否存在 |
#!/bin/bash
filename="/usr/zheng/text.sh"
if [ -r $filename ]
then
cat /usr/zheng/text.sh
else
echo "filename can not read"
fi
字符串
单引号和双引号的区别
- 单引号
- 单引号的中的任何字符都会原样输出
- 单引号中的变量是无效的
- 单引号中不能出现单引号(使用转义字符也不行)
- 双引号
- 双引号中可以有变量
- 可以出现转义字符
- 可以出现单引号
例:
str='123'
name="hh$str"
echo -e "hello,"$name"!\n"
echo "hello,"$name"!\n"
echo "hello,\"$name\"!"
输出:
hello,hh123!\n
hello,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/bash
array=("name"
"+"
"hello"
)
echo ${array[@]}
#array[0]="hello"
str=${arrry[0]}
array[5]=${array[3]}
echo ${array[0]}
echo ${array[5]}
echo ${#array[*]}
输出:
name + hello
name
4
echo
printf
条件判断
- if…fi
- if…else …fi
- if…elif…else…fi
注意事项:
判断条件使用[]包含 表达式和[]之间需要由空格隔开
read
读取命令行输入内容,赋值给变量
如:
read NAME
echo "I LOVE YOU , $NAME!"
输出当前时间
echo date +%F
定义空数组
arr=()
整数自增
tmp=0
1.let tmp++
2.let tmp+=1
3.tmp=`expr $a + 1`
4.$(($tmp+1))
for循环
for j in ${arr[@]}
do
if [ $j == Tools ]; then
let tmp++
fi
done
if判断
if [ $tmp == 2 ];then
echo $date
else
echo ""
fi
脚本命令返回结果转数组
定义数组,为其将返回结果保存在()中,()中是脚本命令。
数组输出时使用 {}包裹,如echo ${arr[0]}
,不适用{}包裹会出现输出问题。
#! /bin/bash
lineNum=`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++))
do
echo ${arr[$i]}
done
for循环遍历
循环体使用do和done包裹
可以使用in
for j in ${arr[@]}
do
if [ $j == Tools ]; then
let tmp++
fi
done
也可以类似java,注意括号
#注意使用两个括号
for ((i=0; i<$lineNum; i++))
do
echo ${arr[$i]}
done
脚本后台执行
输入输出
0:标准输入
1:标准输出
2:错误输出
/dev/null:linux中的黑洞文件,添加到该文件的数据都被删除。
nohup:后台执行,不占用当前窗口,用在命令开头
&:后台执行,用在命令结尾。
nohup /tmp/test.sh > /test.txt 2>&1 &;
nohup /tmp/test.sh > /dev/nul &;