syntax
1.基本布局
#! /bin/bash
2.须知
2.1 在sh中用ssh登录别的节点执行命令,别的节点反馈的控制台信息也会在执行sh的节点控制台打印出来
3.入参
标识符 | desc |
---|---|
$* | 指的是所有输入 |
$index | 第index个参数 |
$# | 参数的个数 |
4.变量
给变量赋值,引号
5.流程控制
5.1 选择
if [ $a == $b ]
then
echo "a is equal to b"
elif [ $a -gt $b ]
then
echo "a is greater than b"
elif [ $a -lt $b ]
then
echo "a is less than b"
else
echo "None of the condition met"
fi
5.2 循环
for i in {1..5}
do
echo $i
done
for i in 5 6 7 8 9
do
echo $i
done
for FILE in $HOME/.bash*
do
echo $FILE
done
break #跳出所有循环
break n #跳出第n层f循环
continue #跳出当前循环
COUNTER=0
while [ $COUNTER -lt 5 ]
do
COUNTER=`expr $COUNTER + 1`
echo $COUNTER
done
case $变量名 in
"值 1")
;;
如果变量的值等于值1,则执行程序1,值
"值 2")
如果变量的值等于值2,则执行程序2
…省略其他分支…
;;
*)
如果变量的值都不是以上的值,则执行此程序
;;
esac
6.函数
shell中定义函数有3种方式,这3种方式等价
f_name(){……}
function f_name{……}
function f_name(){……}
传参,注意定义时的括号里面不需要形参,在函数体中通过$num直接用即可。注意,函数中的\$num和脚本的\$num不同
。
test(){
echo $1 #接收第一个参数
echo $2 #接收第二个参数
echo $3 #接收第三个参数
echo $# #接收到参数的个数
echo $* #接收到的所有参数
}
test aa bb cc
如果这个函数想要在脚本之外用,EXPORT 函数名
调用时,直接函数名 arg1 arg2
7.重定向和追加
$echo result > file #将结果写入文件,结果不会在控制台展示,而是在文件中,覆盖写
$echo result >> file #将结果写入文件,结果不会在控制台展示,而是在文件中,追加写
常用命令
- echo
输出的内容带不带引号都行 - ssh
- sleep
example
1.CDH启停
#! /bin/bash
#1 判断参数个数,如无参数输入,直接退出
argscount=$#
if((argscount == 0));
then
echo ============================no args============================
exit;
fi
#2 函数封装
function start(){
echo ============================启动CDH:begin============================
# 判断mysql是否启动,如果没启动,先启动mysql
mysqlPortStat=`netstat -anp | grep 3306 | wc -l`
if [ $mysqlPortStat == 0 ]
then
ssh node105 systemctl start mysqld
fi
echo "mysql 已经启动"
# 启动CDH
sleep 1s;
ssh node105 /opt/cm-5.16.2/etc/init.d/cloudera-scm-server $1
for((host=105;host < 108;host++));
do
ssh node$host /opt/cm-5.16.2/etc/init.d/cloudera-scm-agent $1
done
# 获取当前前后时间的从1970UTC为止的秒数
start_datetime=`date +%s`
# CDH启动最起码需要等待30s,所以先sleep 30s; 然后再轮循
sleep 30s;
# 监控7180端口,如果监听到数量大于0,说明CDH启动完成
CDHPortCount=`netstat -anp | grep 7180 | wc -l`
while [ $CDHPortCount == 0 ]
do
CDHPortCount=`netstat -anp | grep 7180 | wc -l`
sleep 5s;
done
end_datetime=`date +%s`
echo $end_datetime
echo ============================启动CDH:successed,等待$[end_datetime-start_datetime]s============================
}
function stop(){
echo ============================停止CDH:begin============================
for((host=105;host < 108;host++));do
ssh node$host /opt/cm-5.16.2/etc/init.d/cloudera-scm-agent $1
done
ssh node105 /opt/cm-5.16.2/etc/init.d/cloudera-scm-server $1
echo ============================停止CDH:successed============================
}
function restart(){
# 判断mysql是否启动,如果没启动,先启动mysql
mysqlPortStat=`netstat -anp | grep 3306 | wc -l`
if [ $mysqlPortStat == 0 ]
then
ssh node105 systemctl start mysqld
fi
echo "mysql 已经启动"
#
echo ============================重启CDH:begin============================
for((host=105;host < 108;host++));
do
ssh node$host /opt/cm-5.16.2/etc/init.d/cloudera-scm-agent $1
done
ssh node105 /opt/cm-5.16.2/etc/init.d/cloudera-scm-server $1
echo ============================重启CDH:successed============================
}
#3 根据输入参数执行相应操作
case $1 in
"start")
start $1;
;;
"stop")
stop $1;
;;
"restart")
restart $1;
;;
esac
2.rrsync分发脚本
#!/bin/bash
#1 获取输入参数个数,如果没有参数,直接退出
pcount=$#
if((pcount==0)); then
echo no args;
exit;
fi
#2 获取文件名称
p1=$1
fname=`basename $p1`
echo fname=$fname
#3 获取上级目录到绝对路径
pdir=`cd -P $(dirname $p1); pwd`
echo pdir=$pdir
#4 获取当前用户名称
user=`whoami`
#5 循环
for((host=105; host<108; host++)); do
echo ------------------- node$host --------------
rsync -rvl $pdir/$fname $user@node$host:$pdir
done
3.xcall统一执行脚本
#! /bin/bash
for i in node105 node106 node107
do
echo --------- $i ----------
ssh $i "$*"
done