Shell 编程基础,实战:编写curl小工具,发送post请求
- 脚本的执行方式
- bash hello.sh
- sh hello.sh
- ./hello.sh 必须有可执行权限 chmod +x hello.sh
- source hello.sh
基础语法 ( ) / ()/ ()/{}
$() 等同于 ``
#例如
echo $(date)
echo `date`
# ${} 使用变量引用 可用不适用括号
echo $today # 等同于 echo ${today}
# $(()) 是一种数学计算命令
如
i=1
echo "$((++i))"
echo "$((i+=5))"
- 声明变量
name=hello //=两边不能有空格
echo $name //或 echo ${name}
数据类型
字符串
字符串的声明可以使用 单引号或双引号,或不使用引号,例如:
name="cheng"
name='cheng'
name=cheng
full_name="jack $name" //这里一定要使用双引号,否则$name无法识别为变量
full_name='jack '$name'' //这样也是可以的,建议使用上面的
# 使用
echo $name
-- 输出字符串的长度使用#
echo ${#full_name}
-- 截取字符串长度
echo ${full_name:2:6} -->ck che
数组
arr=('hello' 'world') 、、中间要以空格隔开
echo ${arr[0]} --hello
echo ${arr[@]} --hello world 取出所有的元素
echo ${#arr[@]} --2 数组长度2 或者echo ${#arr[*]}
运算符
a=10
b=20
方式一:
echo `expr $a + $b` --30
方式二:
echo $(($a + $b)) --30
方式三:
echo $[a + b] --30
加减乘除取余(+-*/%)使用上述三种方式均可,注意中间运算符两边必须要有空格
逻辑比较
运算符 | 说明 | 语法 |
---|---|---|
== | 比较两个数是否相等 | [$a == $b] ,相等返回true |
!= | 比较两个数是否不相等 | [$a != $b] ,不等返回true |
-eq | 比较两个数字是否相等 | [$a -eq $b] ,相等返回true |
-ne | 比较两个数字是否不相等 | [$a -ne $b] ,不相等返回true |
-gt | 比较两个数字大小,数学符号:> | [$a -gt $b] ,a大于b等返回true |
-lt | 比较两个数字大小,数学符号:< | [$a -lt $b] ,a小于b等返回true |
-ge | 比较两个数字大于等于,数学符号:>= | [$a -gt $b] ,a大于等于b等返回true |
-le | 比较两个数字大于等于,数学符号:<= | [$a -lt $b] ,a小于等于b等返回true |
-o 或|| | 或运算,相当于OR 比较两个两表达式是否相等 | [$a -lt $b -o 100 < 200 ] ,有一个表达式满足返回true |
-a 或&& | 且运算,相等于and | [$a -lt $b -a 100 < 200 ] ,两个表达式都满足返回true |
字符串比较
[ $name ] --不为空返回true
[ -z $name ] --字符串长度为0,返回true
[ -n $name ] --字符串长度不为0,返回true
[ $name ] --不为空返回true
[ $a = $b ] --两个字符串是否相等,相等返回true
例如:
#/bin/bash
a=10
b=10
if [ $a = $b ]
then
echo 'a等于b'
fi
#############
c=1
d=2
if [ $c -lt $d ]
then
echo 'c小于d'
fi
文件判断
- -r :可读
- -w :可写
- -x :可执行
- -f : 是普通文件
- -d : 是文件目录
- -s :文件不为空
- -e:文件存在
例如:
file=/usr/local/hello.sh
if [ -r $file ]
then
echo '文件可读'
fi
常见语法(if,case,while,for,函数)
if
if [ ]
then
#do something
else
#do something
if
case
#/bin/bash
echo '请输入一个数字'
read num
case $num in
1) echo '您输入了一个1'
;;
2) echo '您输入了一个2'
;;
*) echo '您输入的非1,非2的数字='$num''
esac
while/for循环
#/bin/bash
int=0
while(($int <= 10))
do
echo "数字int=$int"
let "int++" #let 不需要加$
done
//死循环
while true
do
dosomething
done
# while 与if结合使用,获取用户有效输入
echo '请输入url'
while true
do
read -e url
if [ $url ]
then
break
else
echo 'url输入有误,请重新输入'
fi
done
# for循环
for((i=0;i<5;i++))
do
echo $i
done
# for循环一个数组
tables=('user' 'loan')
for tb in ${tables[@]}
do
echo $tb
done
function
#/bin/bash
function addfun(){
echo '请输入第一额数'
read a
echo '请输入第二个数字'
read b
return $(($a + $b))
}
addfun #调用函数
echo "两个数字之和是:$?" # 函数的返回值可以通过$?获取
打包/压缩/解压缩
tar
tar是打包操作,可以适用一些压缩算法来进行压缩,tar 打包默认保留源文件。
打包压缩
tar zcvf data.tar.gz *.sql
解释:
-z : 适用gzip的算法打包
-c : create 打包,创建文件,-x 解压缩
-v : 显示打包过程
-f : 表示压缩的来自文件 file
打包时排除一个文件
tar -zcvf data.tar.gz *.sql --exclude user.sql # 打包所有的*.sql 排除user.sql文件
解压缩:
tar zxvf data.tar.gz 默认当前文件下
tar -zxvf data.tar.gz -C temp/ 指定解压缩的文件路径
解压缩包内的单独文件
tar -zxvf data.tar.gz [单独的文件]
如:
tar -zxvf data.tar.gz user.sql # 只解压缩user.sql这个文件
gzip
gzip,专门用于文件的压缩和解压缩工具,默认覆盖原文件。
压缩命令:
gzip 文件
如:gzip *.sql # 默认在原文件名后增加.gz后缀,同时覆盖原文件
解压缩
gunzip *.gz # 解压缩文件,解压缩后覆盖.gz文件
zip
压缩
zip 压缩后的文件名 压缩的源文件
zip data.zip *.sql
压缩目录
zip -r datadir.zip ./
解压缩
unzip data.zip
解压缩
实战:编写一个curl工具类,用于测试post,发送json参数请求
实现功能:
- 可以输入请求参数
- 可以输入请求地址
- 执行后记录到日志文件
#!/bin/bash
# curl 工具类,实现post请求
cmd=$1
date=`date +'%F %H:%M:%S.%N'`
log_dir=log
log_file=$log_dir/curl-`date +%F`.log
echo '请输入请求参数request body'
read -e req_param
# read -e :可以退格
echo '请输入url'
while true
do
read -e url
if [ $url ]
then
break
else
echo 'url输入有误,请重新输入'
fi
done
echo "正在请求url:$url ..."
result=
if [ $cmd == 'GET' ]
then
result=`curl -X GET "${req_param}" $url `
else
result=`curl -X POST -d '${req_param}' $url`
cmd='POST'
fi
echo $result
# 判断文件是否存在,不存在创建
if [ ! -e $log_dir ]
then
mkdir -p $log_dir
fi
echo $log_file
echo "$date request-type:$cmd, request-body:$req_param request-url:$url , result:$result" >> $log_file
测试
chmod +x curl.sh
./curl.sh GET
实战二:
写一个shell脚本实现不同的数据库的两张表每天汇总到一张表中
#!/bin/bash
#编写复制数据库脚本
username=root
password=root
host=192.168.1.13
delete_sql="truncate table new.user_new;"
springmvc_user_sql="insert into new.user_new(id,
name,
age,
sex,
parent_name,
parent_id
)
select * from springmvc.user;"
new_user_sql="
insert into new.user_new(
id,
name,
age,
sex,
parent_name,
parent_id
)
select * from new.user;"
mysql -u$username -p$password -h$host -e "$delete_sql";
echo '清除原数据成功'
mysql -u$username -p$password -h$host -e "${springmvc_user_sql}";
echo '导入数据spring_mvc.user完成'
mysql -u$username -p$password -h$host -e "$new_user_sql";
echo '导入数据new.user 完成'
exit
实战:按照表名备份mysql数据库
#!/bin/bash
# 导出处数据库,单个表导入同一个文件
host=192.168.1.13
user=root
password=root
# 需要备份的库
database=springmvc
# 需要备份的表,多个适用空格隔开
tables=('user' 'loan')
# 数据库选项
# --skip-add-drop-table 跳过drop table语句,默认开启
# --no-create-info 简写-t 跳过创建表语句,默认开启
# --skip-lock-tables 不锁表,默认开启
#
opt='--no-create-info --skip-add-drop-table'
# 文件输出路径
bakdir=/home/mysqlbak/data
if [ ! -d $bakdir ]
then
mkdir $bakdir
fi
start_s=`date +%s`
for tb in ${tables[@]}
do
/usr/local/mysql/bin/mysqldump -u$user -p$password -h$host $opt $database $tb > $bakdir/''$tb'.sql'
#导出数据库并压缩,解压缩 gzip -d -c user.sql.gz > gz/user.sql3
# /usr/local/mysql/bin/mysqldump -u$user -p$password -h$host $opt $database $tb | gzip > ./data/''$tb'.sql.gz'
done
end_s=`date +%s`
time_count=$(( $end_s - $start_s ))
echo "耗时:${time_count}秒"
vim 操作技巧
1. 删除指定行
:3,10d # 删除第3到10行
2.光标移动到第几行
3G # 移动到第三行
3- 光标向右/向左移动多少字符
100l #向后移动100列
100h #向左移动100个字符
j 向下移动行
2j #向下移动2行
k 向上移动行
2k #向上移动2行
w/b 正向/反向移动到下一个单词
2w #移动到后面2个单词
2b #反向移动到前面2个单词
4 删除后面多少个字符
5x #删除后面5个字符
删除指定行(命令模式:)
3,5d #删除3到5行