0.linux shell脚本编程
对于一些简单的操作,我们可以直接通过在linux 命令行执行就可以了,比如列出文件命令ls -l,但是有时候我们需要完成的任务需要连续执行多条linux命令,而且他们之间具有一定的执行逻辑,这时候直接通过命令行输入就不是一种比较好的办法了。
这时候我们可以利用linux shell的语法,编写脚本,主要的好处有俩点,一方面可以编写复杂的执行逻辑,实现自动化,另一方面通用的脚本可以重复利用,而无需每次都手动编写命令。
开始linux shell编程非常简单,只需新建后缀名为.sh的文本文件第一行加
#!/bin/bash 指定解释器,一般默认就是这个
然后执行
chmod +x test.sh # 给予test.sh可执行的权限
./test.sh # 执行test.sh 也可以用bash test.sh
1.变量
1.1 变量定义及使用
linux shell变量定义不需要使用美元符,但使用的时候需要,{}可选但一般建议加,用在if判断的时候最好加双引号
a="hello world!"
echo $a
# 如果不加{}就被当$namescript了
name="java"
echo ${name}script
# 这里$str必须加双引号,否则会报错,因为$str为空的时候就变成了 if [ -n ]
if [ -n "$str" ] ;then
echo "$str为空"
fi
单引号中的字符会原样输出,变量会失效,而双引号不会
变量也可以接受linux命令的结果,关键是要把命令用反引号包围起来
如将ping的结果赋值给变量
HOSTNAME=abc.com
ping_str=`ping -c 4 ${HOSTNAME}` #-c 指定ping几次
1.2 一些常用特殊变量
$JAVA_HOME # java的环境变量如/usr/local/java/jdk1.8.0
$# #可以表示传入脚本的参数个数,也可以表示传入函数的参数个数
$? 显示最后命令的退出状态,0表示上一条命令执行正确无错误
值得注意的是$?表示的是上一条命令的退出状态,用它可以判断上一条命令执行是否成功,但是当函数中有多条命令的时候,用它无法判断函数是否出错,因为函数中间的语句出错【不影响】脚本会继续执行的时候,只要函数的最后一句没有出错,那么$?就会返回0
2.字符串和数组
2.1 字符串
shell中字符串可以不加引号,如直接
echo hello
也可以使用单引号
echo 'hello'
var="world"
echo 'hello,$var'
# 结果为 hello,$var
当然也可以双引号
echo "hello"
var="world"
echo "hello,$var"
结果为 hello,world
单引号中变量不会被解析,因此单引号不可以输出变量,双引号中可以输出变量
对字符串的常用操作
# 获取字符串长度
str="abcdef"
${#str}
# 截取字符串
${str:1:3}
# 查找子字符串位置
index=`expr index $str bc` #注意是反引号
2.2 数组
数组定义
arr=(1 2 3 4 5)
# 或者
arr[0]=1
arr[1]=2
arr[2]=3
对数组的常用操作
#取元素
${arr[0]} # 取第0个元素
${arr[@]} # 取全部元素
#获取数组长度
${#arr[@]}
# 将某些命令返回的结果转为数组
arr=(`fdisk -l | grep -v identifier | grep Disk`)
#遍历数组
for var in ${arr[@]}
do
echo $var
done
3.运算符
3.1 算术运算符
+ - * / = == !=
= == !=和其他语言没什么区别,关键是+ - * /不大一样,直接a=1+1没什么卵用,通常有三种做法
var=`expr 1 + 1 ` #注意数字和操作符之间要有空格
let var='1+1' # 用let语法 数字和操作符之间不需要空格 不加引号也可以
var=$((1+2)) # 注意加$
用expr 这种方法时候*要加反斜杠转义
3.2关系运算符
-eq 相等返回true
-gt 前边大返回true -ge 大于等于
-lt 前边小返回true -le 小于等于
关系运算符只支持数字
3.3布尔运算符和逻辑运算符
! 不等
-o 或
-a 与
&& 且
|| 或
使用&&和||的时候,条件要用俩个[],如[condition1] && [condition2] 或者[[ condition1 && condition2 ]]
3.4 shell特有运算符
有关字符串的
-z 字符串长度为0 返回true
-n 字符串长度不为0 返回true
判断相等与不等 可以用==和!=
有关文件的
-f 判断文件是否为普通文件 是返回true
-x 判断文件是否可执行 是返回true
-d 判断文件是否为目录 是返回true
-w 判断文件是否可写 是返回true
-r 判断文件是否可读 是返回true
if [ -n $str ]
then
echo "str不为空"
fi
# 也可以不用任何运算符
if [ $str ]
then
"$str不为空"
fi
# 目录不存在则创建
if [ ! -d /usr/local/test ]
then
mkdir /usr/local/test
fi
4.函数
函数定义:可以省略function关键字,且参数不必在定义中体现,"#"表示传进来的参数个数,"1"表示第一个参数,"$2"表示第二个参数...
function doSomething(){
}
linux shell 的函数只能返回[0-255]的整数值,如果你想返回其他东西,如字符串,不要用return,要用echo,但是要注意,你拿变量接收echo的值的时候会接收你函数中所有echo的值,但很多时候这不是你想要的,所以需要注意。
5.流程控制
5.1 if-else
if [ $num -gt 100 ] && [ $num -lt 1000 ]
then
echo "num大于100小于1000"
elif [ $num -gt 1000 ]
then
echo "num大于1000"
else
echo "小于100"
fi
完整语法如上,也可以像其他语言一样,只用if
if [ $num -eq 100 ]
then
echo "num等于100"
fi
要注意的是语法与我们常见的不同,then,fi都不要忘
[ 条件一 ] 条件不能与放括弧挨着,否则会报错
使用 && 是[ 条件一 ] &&
[ 条件二 ] 而不是 [ 条件一 && 条件二 ]
5.2 for循环和while循环
for循环形式一
for var in 1 2 3 4 5
do
echo "$var"
done
for循环形式二
for ((i=0;i<$num;i++))
do
echo "$i"
done
注意形式二中圆括号是俩个,想不懂为什么要这样
while循环形式一
while (($i<5))
do
echo "$i"
i=$(($i+1))
done
while循环形式二
while [ condition ]
do
echo "i am a while circle"
done
注意第一种while循环中变量赋值
6.其他技巧
echo输出太单调?可以先定义几个日志函数,不同级别输出不同的颜色,如最基本的info输出蓝色,错误输出红色
function log_error(){
echo -e "\033[31;40m[ERROR] $1 \033[0m"
}
function log_info(){
echo -e "\033[40;36m[INFO] $1 \033[0m"
}