1.什么是shell?
1.一个编程的语言
2.可以执行的文件
3.文件内容 linux 命令组成的
2.shell语法入门
入门
1.文件 xxx.sh 文件
2.第一行 #!/bin/bash
1.编写脚本
[root@liunxandshell shell]# vim hello.sh
#!/bin/bash
echo "world count"
2.得有执行权限【不一定】
1.不给文件权限 执行
[root@liunxandshell shell]# sh ./hello.sh
world count
[root@liunxandshell shell]# cat ./hello.sh
#!/bin/bash
echo "world count"
2.给文件 执行权限【推荐】
[root@liunxandshell shell]# chmod 744 ./hello.sh
[root@liunxandshell shell]# sh ./hello.sh
world count
[root@liunxandshell shell]# ./hello.sh
world count
补充:
1.给权限
赋予权限的第二种方式
[root@liunxandshell shell]# chmod u+x ./hello.sh
[root@liunxandshell shell]# ./hello.sh
world count
2.执行路径
绝对路径执行
[root@liunxandshell shell]# /root/shell/hello.sh
world count
[root@liunxandshell shell]# sh /root/shell/hello.sh
world count
3.debug
1.sh -x
【加号是debug过程中】
[root@liunxandshell shell]# sh -x ./hello.sh
+ echo 'world count'
world count
2.文件内
【在第一行加上 -x】
#!/bin/bash -x
echo "world count"
[root@liunxandshell shell]# ./hello.sh
+ echo 'world count'
world count
思考:sh 可以grep吗? 【意义不大,还得研究】
[root@liunxandshell shell]# cat variable.sh
name="xianyu"
dt1="date"
dt2=`date`
echo ${name}
echo ${dt1}
echo ${dt2}
[root@liunxandshell shell]# ./variable.sh | grep date
date
[root@liunxandshell shell]# sh -x ./variable.sh | grep date
+ name=xianyu
+ dt1=date
++ date
+ dt2='2022年 04月 14日 星期四 10:22:08 CST'
+ echo xianyu
+ echo date
+ echo 2022年 04月 14日 星期四 10:22:08 CST
date
[root@liunxandshell shell]# sh -x ./variable.sh | grep xianyu
+ name=xianyu
+ dt1=date
++ date
+ dt2='2022年 04月 14日 星期四 10:39:59 CST'
+ echo xianyu
+ echo date_1
+ echo 2022年 04月 14日 星期四 10:39:59 CST
xianyu
2.定义变量
案例
[root@liunxandshell shell]# cat variable.sh
name="xianyu"
dt1="date"
dt2=`date`
echo ${name}
echo ${dt1}
echo ${dt2}
[root@liunxandshell shell]# ./variable.sh
xianyu
date
2022年 04月 14日 星期四 10:19:06 CST
1.定义变量的方式:
key=value
注意:
1.= 前后不能有空格
2.变量名一般都是大写的
2.变量的种类
shell中变量的数据类型 => string
1.静态
k="v" k='v' k=v
2.动态
k=`v` :v是变量 v系统自带的命令
3.引用
1.$k
2.${k}【建议使用这个,可以在后面拼接字符串】
任务调度:
shell =>
时间点 T+1 、 h+1 20min
20220414 =》 20220413
20220414 0:05
1.yarn资源【这块有实时监控yarn资源的项目】
2.看你几点上班,上班之前跑出来
公司在意有没有一个真正解决问题的东西
crontab 命令 =》 定时调度
开源框架:
dophinscheduler【最好用,恢复数据、重跑数据】[https://dolphinscheduler.apache.org/zh-cn/](https://dolphinscheduler.apache.org/zh-cn/)
xxl【好用 shell脚本填进去】
airflow【费劲但好用】
runduck
自己开发
azkaban => 血缘关系 【数仓任务】 => Apache Atlas元数据血缘关系【比较鸡肋,不太好用】
done => mysql => web
java
maven
quickstart
3.参数传递
1.$n
$1 $2 ...
案例
[root@liunxandshell ~]# cat ./par.sh
echo "脚本文件名:$0"
echo "第一个参数:$1"
echo "第二个参数:$2"
echo "参数个数:$#"
echo "传递的参数作为一个字符串:$*"
echo "传递的参数作为一个字符串:$@"
echo "脚本运行时的pid:$$"
最后一行的意义:
# 假如是一个实时程序,要通过pid来查
# ps -ef | grep sparkxxx => pid kill可能会kill错
[root@liunxandshell ~]# ./par.sh "hello word" word2
脚本文件名:./par.sh
第一个参数:hello word
第二个参数:word2
参数个数:2
传递的参数作为一个字符串:hello word word2
传递的参数作为一个字符串:hello word word2
脚本运行时的pid:6721
补充:
1.传递参数 “空格” 作为符号分割
2.参数本身带有空格 要加双引号
4.数组
语法格式:
arr=(v1 v2 ... vn)
1.数组用()表示
2.元素用 空格 分割
案例
[root@liunxandshell ~]# cat arr.sh
arr=(xy lxy dxy haha)
echo "所有元素:${arr[@]}"
echo "第一个元素:${arr[0]}"
echo "元素个数:${#arr[@]}"
[root@liunxandshell ~]# ./arr.sh
所有元素:xy lxy dxy haha
第一个元素:xy
元素个数:4
5.流程控制
条件表达式 不能用 < >
1.分支if else
语法格式:
if condition;then
业务代码
else
业务代码
fi
condition => 条件判断语法
[ condition ]
注意:前后都是有空格的
结果:
非空 true
空 false
[ hadoop ]
$? => 获取上一个程序运行的结果
1.成功 0
2.失败 非0的数
案例
[root@liunxandshell shell]# [ hadoop ]
[root@liunxandshell shell]# echo $?
0
2.分支if elif else
语法结构
if condition;then
业务代码
elseif condition;then
else
业务代码
fi
案例
score=$1
if [ ${score} -gt 90 ];then
echo "优秀"
elif [ ${score} -ge 60 ];then
echo "良"
else
echo "不及格"
fi
3.条件表达式
1.数值判断
= 等于
== 等于
-lt 小于
-eq 等于
-ge 大于等于
-le 小于等于
-gt 大于
-ne 不等于
案例
name1="xy"
name2="lxy"
if [ ${name1} == ${name2} ];then
echo "等于"
else
echo "不等于"
fi
[root@liunxandshell shell]# ./if.sh
不等于
2.权限判断
-r
-w
-x
3.文件判断
-f
-e
-d
4.循环
while for 能用 < > 不能用 -gt
1.foreach
foreach:
for el in item1 item2 ...itemn 【这可以 for el in arr】
do
业务代码
done
案例
for x in 1 2 3 4
do
echo "${x}"
done
2.for i
for ((i=0;i<size;i++))
do
业务代码
done
案例
for ((i=0;i<5;i++))
do
echo "v is ${i}"
done
3.while:
while condition
do
业务代码
done
案例【<= 不能换 -le】
[root@liunxandshell shell]# cat ./while.sh
i=1
while(($i<=5))
do
echo "v is ${i}"
let i++
done
流程控制总结:
条件表达式 不能用 < >
while for 能用 < > 不能用 -gt
[https://www.cnblogs.com/qlqwjy/p/8684630.html](https://www.cnblogs.com/qlqwjy/p/8684630.html)
区别: [] 和 ()
[] => 条件判断
() => 用于 数值运算
[root@liunxandshell shell]# echo $[1+2]
3
[root@liunxandshell shell]# echo $((1+2))
3
案例:监控 服务器
ip hostname
linux01 linux02 linux03
df 磁盘
free 内存
不要指定多个参数,最好一个字符串替换
str="linux01,linux02,linux03"
替换
arr=(${str//,/ })
for linux in ${arr[@]}
do
echo "${linux}"
done
[root@liunxandshell shell]# ./split.sh
linux01
linux02
linux03
srt.split(",") 【好好掌握】
shell =>
IFS变量 => 字符串分割的效果
补充: linux 文本分析的 命令
awk => 取出文本内容
sed => 文本替换
1.awk【多用某个框架的启动和停止脚本】
数据
[root@liunxandshell shell]# cat 1.log
a b c
1 2 3
1.获取列
[root@liunxandshell shell]# cat 1.log | awk '{print $1}'
a
1
[root@liunxandshell shell]# cat 1.log | awk '{print $1,$2}'
a b
1 2
2.获取行
[root@liunxandshell shell]# cat 1.log | awk 'NR==1{print}'
a b c
[root@liunxandshell shell]# cat 1.log | awk 'NR==2{print}'
1 2 3
[root@liunxandshell shell]# cat 1.log | awk 'NR>1{print}'
1 2 3
[root@liunxandshell shell]# cat 1.log | awk 'NR>=1{print}'
a b c
1 2 3
2.sed
文本替换
数据
[root@liunxandshell shell]# cat 2.log
a a b
1 a 3
1.a 替换成 dd
[root@liunxandshell shell]# sed -i 's/a/dd/' 2.log #每行第一次遇到a替换成dd
[root@liunxandshell shell]# cat 2.log
dd a b
1 dd 3
2.全局替换
sed -i 's/a/dd/g' 2.log
[root@liunxandshell shell]# sed -i 's/a/dd/g' 2.log
[root@liunxandshell shell]# cat 2.log
dd dd b
1 dd 3
坑:
【's/a/dd/g'不一定用反斜杠,也可以用# sed -i 's#dd#b#g' 2.log】
替换文件路径
/path/a
p1="/path/a" => 换成
p1="/path1/a1"
看不懂
sed -i 's/\/path\/a/\/path1\/a1/g' 3.log
[root@liunxandshell shell]# sed -i 's/\/path\/a/\/path1\/a1/g' 3.log
[root@liunxandshell shell]# cat 3.log
p1="/path1/a1"
舒适易读
sed -i 's#/path/a#/path1/a1#g' 3.log
[root@liunxandshell shell]# sed -i 's#/path/a#/path1/a1#g' 3.log
[root@liunxandshell shell]# cat 3.log
p1="/path1/a1"