Shell 脚本基础和应用实例
1 shell 简介和说明
Shell 既是一种命令语言,又是一种程序设计语言。Shell 是指一种应用程序,这个应用程序提供了一个界面,用户通过这个界面访问操作系统内核的服务
Shell 脚本(shell script),是一种为 shell 编写的脚本程序。
需要写代码的文本编辑器和解释执行的脚本解释器
Linux 的 Shell 种类众多,常见的有:
Bourne Shell (/usr/bin sh 或者 /bin/sh)
Bourne Again Shell (/bin/bash)
主要学习bash
vim一个test.sh文件
#!/bin/bash。--约定的标记,它告诉系统这个脚本需要什么解释器来执行(使用哪一种 Shell)
echo "Hello World !”。--向窗口输出
运行前先设定脚本有执行权限:chmod +x ./test.sh
./test.sh. ./ 是表示在当前目录找
2 Shell 变量
变量名和等号之间不能有空格,注意命名规则 如:your_name="runoob.com"
使用变量:在变量名前面加美元符号 echo $your_name 或者echo ${your_name}
变量可以被重新定义
只读变量不能被重新定义
readonly your_name
删除变量:unset variable_name
变量类型:
局部变量 只在当前shell实例中生效,其他shell程序不能访问
环境变量
shell变量
3 Shell字符串
单双引字符串
str=“hello, I know you are \”$your_name\” \n” 双引号里可以有变量和转义字符
拼接字符串
greeting_1="hello, ${your_name} !”
greeting_3='hello, ${your_name} !’
获取字符串长度
str=“abcd"
echo ${#string}#输出 4
提取子字符串
string="runoob is a great site"
echo ${string:1:4}# 输出 unoo
获取子字符串
查找字符 i 或 o 的位置
string="runoob is a great site"
echo`expr index "$string" io` # 输出 4 expr--是一个手工命令行计数器
4 Shell数组
数组名=(值1值2...值n)
比如:array_name=(value0 value1 value2 value3)
my_array=(A B"C"D)
array_name[0]=value0
读取数组:${数组名[下标]} ${array_name[index]}
比如valuen=${array_name[n]}
echo ${array_name[@]} —-- @或者*符号可以获取数组中所有元素
获取数组长度
# 取得数组元素的个数
length=${#array_name[@]}
# 或者
length=${#array_name[*]}
# 取得数组单个元素的长度
lengthn=${#array_name[n]}
4 shell注释
#注释
:<<‘
注释内容
‘
5 参数传递
#!/bin/bash
# url:www.baidu.com
echo"Shell 传递参数实例!";
echo"第一个参数为:$1";
echo"参数个数为:$#";
echo"传递的参数作为一个字符串显示:$*”;
$ chmod+x test.sh
$./test.sh123
Shell传递参数实例!
第一个参数为:1
参数个数为:3
传递的参数作为一个字符串显示:123
$* 与 $@ 区别:
5 运算符
基本运算符
乘号(*)前边必须加反斜杠(\)才能实现乘法运算
在 MAC 中 shell 的 expr 语法是:$((表达式))
条件表达式要放在方括号之间,并且要有空格,例如: [$a==$b] 是错误的,必须写成 [ $a == $b ]。
表达式和运算符之间要有空格,例如 2+2 是不对的,必须写成 2 + 2
关系运算符
-eq 等于则为真
-ne 不等于则为真
-gt 大于则为真
-lt 小于则为真
-ge 大于等于则为真
-le 小于等于则为真
布尔运算符
! 非 -o 或 -a 与
逻辑运算符
&& 逻辑AND
||逻辑OR
字符串运算符
= !=
-z 字符串长度为零则为真
-n 字符串长度不为零则为真
$ 字符串不为空为真
文件测试运算符
-b file
-d file
-f file
-r file
-s file
-e file
6 echo 命令
echo-e"OK! \n"开启转义
echo"It is a test">myfile显示结果定向至文件
echo'$name\”’ 原样输出字符串不进行转移或者取值变量
echo`date` 显示执行命令的结果(注意是反引不是单引)
7 shell printf命令
printf format-string [arguments…]
参数说明:
format-string: 为格式控制字符串
arguments: 为参数列表。
printf"%-10s %-8s %-4s\n"姓名性别体重kg
8 shell test命令
num1="ru1noob"
num2="runoob"
iftest $num1=$num2
then
echo'两个字符串相等!'
else
echo'两个字符串不相等!'
fi
9 流程控制
条件判断
ifcondition
then
command1
command2
...
commandN
fi
或者:
if condition1
then
command1
elif condition2
then
command2
else
commandN
fi
for循环
for var in item1 item2...itemN
do
command1
command2
...
commandN
done
while循环
whil econdition
do
command
done
多选
case值in
模式1)
command1
command2
...
commandN
;;
模式2)
command1
command2
...
commandN
;;
esac
10 函数
[function] funname[()]
{
action;
[returnint;]
}
函数返回值在调用该函数后通过 $? 来获得
11 输入输出重定向
command1>file1 输出重定向
command1<file1输入重定向
12 文件引用
test1.sh代码如下
#!/bin/bash
# author:axw
# url:www.baidu.com
test2.sh代码如下:
#!/bin/bash
# author:axw
# url:www.baidu.com
#使用 .号来引用test1.sh文件
../test1.sh
# 或者使用以下包含文件代码
# source ./test1.sh
echo"地址:$url"
shell脚本实际应用举例:
1、比较远程提测分支最新代码、虚拟机当前代码
2、部署远程提测分支最新代码
#!/usr/bin/env bash
# Desc: git commitId compare & reload
# feature涉及git项目
declare -A projects
projects=(
["service_interlogistics"]="feature/hwl-stocking-up-upgrade"
["gateway_aqua"]="feature/hwl-stocking-up-upgrade"
["gateway_adam"]="feature/hwl-stocking-up-upgrade"
)
# git项目路径
code_path="/data/fulishe/"
# 遍历
for project in "${!projects[@]}"; do
branch=${projects[$project]}
echo -e "\n\n[$project] checkout to [$branch]:"
cd $code_path$project/codebase
git fetch
# 比较当前代码、提测分支最新代码
diff_rst=`git diff HEAD origin/$branch --stat`
if [[ $diff_rst = "" ]]; then
# 若当前commit=提测分支最新代码,不部署
echo -e "\nOP: DON'T NEED RELOAD!"
else
# 若当前commit!=提测分支最新代码,部署
echo -e "\nOP: $project RELOAD!"
# 比较idl-spec.yaml
diff_idl=`git diff HEAD origin/$branch --stat idl-spec.yaml`
# 比较requirements.txt
diff_requirements=`git diff HEAD origin/$branch --stat requirements.txt`
git stash
# 切换分支
git checkout origin/$branch
if [[ $diff_idl = "" ]]; then
echo -e "\nOP: idl-spec.yaml no change, DON'T need flsthrift!"
else
echo -e "\nOP: idl-spec.yaml change, $project flsthrift:"
flsthrift
fi
if [[ $diff_requirements = "" ]]; then
echo -e "\nOP: requirements.txt no change, DON'T need pip install!"
else
echo -e "\nOP: requirements.txt change, $project pip install:"
pip install -r requirements.txt
fi
# 重启服务
echo -e "\nOP: $project reload & health_check: "
./../command/reload.sh
./../command/health_check
fi
done