shell是用户与内核进行交互操作的一种接口,目前最流行的shell称为bash shell,bashshell编程以其简洁、高效而著称,多年来成为linux程序员和系统管理员解决实际问题的利器。
bash编程是面向过程的,依靠bash解释器边解释边执行,脚本的编写格式:
第一行:写明解释器; #!/bin/bash
注释行:所有以#开头的行均为注释行;会被解释器忽略
下面来看一个经典的小程序:
#!/bin/bash
echo "hello world"
它的第一行表示这个脚本程序由/bin/bash来解释.第二行在终端上打印出一行”Hello World”
一、给脚本传参数
bash脚本我们还可以给它传递参数,在脚本里通过调用位置变量来实现
#!/bin/bash
echo $* #$*表示所有参数列表
echo $@ #$@表示所有参数列表
echo $0 #$0是指脚本名称
echo $1 #$1表示脚本的第1个位置参数
echo $# #$# 表示当前脚本的位置参数个数
二、条件测试
条件测试: test 表达式
[表达式 ]
[[表达式 ]]
测试表达式:
(1) 整数测试: 整数测试:A, B
A -gt B: 大于
A -ge B: 大于等于
A -eq B: 等于
A -lt B: 小于
A -le B: 小于等于
A -ne B: 不等于
(2) 字符串测试: 字符串测试:A, B
A > B
A < B
A >= B
A <= B
A == B或A =B:等值比较
A != B: 不等于
-z A: 判断A是否为空;空则为真,不空则假
-n A:判断A是否不空;不空则为值,空则为假
(3) 文件测试: -e$file: 是否存在;存在则为真
-f $file: 文件是否存在,且为普通文件
-d $file: 是否存在且为目录
-h $file: 是否存在且为符号链接文件
-L $file:同上
-b $file: 是否存在且为块设备文件
-c $file: 是否存在且为字符设备文件
-S $file: 是否存在且为套接字文件
-p $file: 是否存在且为管道文件
-r$file: 当前用户对此文件是否拥有读权限
-w $file: 当前用户对此文件是否拥有写权限
-x $file: 当前用户对此文件是否拥有执行权限
-u$file: 文件是否拥有suid权限
-g $file:文件是否拥有sgid权限
-k $file: 文件是否拥有sticky权限
-O$file: 当前用户是否为文件的属主
-G $file: 当前用户是否属于文件的属组
-N $file:文件自从上一次被读取之后,是否被修改过
$f1 -nt$f2: 文件f1是否比文件f2新
$f1 -ot $f2: 文件f1是否比文件f2旧
$f1 -ef $f2:f1和f2是否为同一个文件的硬链接
三、流程控制
1、for循环
for 变量 in列表; do
循环体
done
如我们要打印1到10,我们可以这样写
#!/bin/bash
for i in {1..10};do
echo "$i"
done
2、if条件判断
if 条件;then
条件为真时执行命令
else
条件为假时执行命令
fi
例如:
#!/bin/bash
if [ 5 -eq 4 ];then
echo "true"
else
echo "false"
fi
3、case条件判断,通常用于判断字符串
case 变量 in
值1)
变量值等于值1执行语句
;;
值2)
变量值等于值2执行语句
;;
*)
变量值等于其他值执行语句
;;
esac
例如:
#!/bin/bash
case $1 in
cpu)
lscpu ;;
*)
exit 0 ;;
esac
4、while和until循环
whileCONDITION; do
循环体
循环控制变量的修正表达式
done
untilCONDITION; do
循环体
循环控制变量修正表达式
done
例如
#!/bin/bash
declare -i i=1
while [ $i -le 10 ];do
echo $i
let i++
done
5、循环控制命令break和continue
break:提前退出循环;
break [N]: 退出N层循环;N省略时表示退出break语句所在的循环;
continue: 提前结束本轮循环,而直接进入下轮循环;
continue [N]:提前第N层的循环的本轮循环,而直接进入下轮循环;
四、函数
定义函数的目的:将有特定功能的代码块,定义一个函数名称,在要使用此代码块时,直接调用函数,而不用再写一遍此代码块,也可以给函数传递参数
function_name(){
函数代码块
}
例如
#!/bin/bash
testfuc() {
echo "test function"
}
testfuc #调用函数testfuc
函数的返回值:
函数中使用打印语句:echo, printf
函数体中OS命令执行结果的输出
函数的退出状态码:
默认取决于函数体执行的最后一个命令的退出状态码;
自定义退出状态码:return [0-255]
注意:函数体运行时,一旦遇到return语句,函数即返回;
五、数组
数组元素:数组名+索引
索引:从0开始编号
声明数组:declare -a ARRAR_NAME
关联数组:declare -A ARRAY_NAME
数组元素的赋值:
(1) 一次只赋值一个元素
ARRAY[index]=VALUE
a[0]="hello"
(2) 一次赋值全部元素
ARRAY=("mon""tue" "wed")
(3) 指定索引进行赋值
ARRAY=([0]="sun"[1]="mon" [5]="fri")
(4) read -a ARRAY
引用数组元素:${ARRAY[index]}
数组的长度: ${#ARRAY[*]}, ${#ARRAY[@]}
例如
#!/bin/bash
declare -a testarry
for i in {0..9};do
testarry[$i]=$RANDOM
done
echo "${testarry[*]}"
六、字符串操作
字符串切片:${var:offset:lenth}
取字符串最后的几个字符:${var: -lenth} 注意:冒号之后有空格
基于模式取子串:
${var#*word}:其中word可以是指定的任意字符;自左而右,查找var变量所存储字符中,第一次出现的word,删除字符开头直至第一次wrod出现处之间的所有字符
${var##*word}: 其中word可以是指定的任意字符;自左而右,查找var变量所存储字符中,最后一次出现的word,删除字符开头直至最后一次wrod出现处之间的所有字符
${var%word*}:自右而左,删除第一次word出现处的字符开始直到尾部的所有字符
${var%%word*}:自右而左,删除最后一次word出现处的字符开始直到尾部的所有字符
例如 : url=http://www.magedu.com:80
取端口:${url##*:}
取协议:${url%%:*}
查找并替换:
${var/pattern/substi}:查找var所表示的字串中,第一次被Pattern匹配到的字串,并以substi替换之
${var//patten/substi}:查找var所表示的字串中,所有被Pattern匹配到的字串,并以substi替换之
${var/#pattern/substi}:以行首锚定的方式将pattern匹配至var所表示的字串上,如果能匹配,则以substi替换之
${var/%pattern/substi}:以行尾锚定的方式将pattern匹配至var所表示的字串上,如果能匹配,则以substi替换之;可使用?, *元字符
查找并删除:
${var/pattern}:删除pattern匹配到的第一次出现;
${var//pattern}:删除pattern匹配到的所有出现;
${var/#pattern}
${var/%pattern}
字符串大小写转换:
${var^^}:小写-->大写
${var,,}:大写-->小写
变量赋值:
${var:-word}:如果var为空或未设置,那么返回word;否则,则返回var中的值;
${var:=word}:如果var为空或未设置,那么返回word,并且将word赋值给var;否则,返回var中的值;
${var:?err_info}:如果var为空或未设置,那么返回错误信息;否则,则返回var自身的值;
${var:+word}:如果var自身有正常数据,则返回word;