您的位置:首页 > 运维架构 > Shell

Shell脚本入门及案例

2020-04-21 19:29 736 查看

一、Shell脚本入门

二、作业

一、Shell脚本入门

需要的基础:Linux命令

1、创建/opt/shell目录,在其下创建一个简单的shell;
[root@hadoop001 shell]# cat helloworld.sh
#!/bin/bash
echo "www.ruozedata.com"

2、执行shell
[root@hadoop001 shell]# /opt/shell/helloworld.sh
-bash: /opt/shell/helloworld.sh: Permission denied
[root@hadoop001 shell]# ./helloworld.sh
-bash: ./helloworld.sh: Permission denied
[root@hadoop001 shell]# pwd
/opt/shell

//为什么提示command not found呢,因为/opt/shell没有配置环境变量:
[root@hadoop001 shell]# helloworld.sh
-bash: helloworld.sh: command not found

3、赋予执行权限,就能直接执行:
[root@hadoop001 shell]# chmod 654 helloworld.sh
[root@hadoop001 shell]# ./helloworld.sh
www.ruozedata.com

//一般不使用+x命令
[root@hadoop001 shell]# chmod +x helloworld.sh

Shell脚本如何进行Debug?

  • 在解释器后面加一个-x,再次进行执行即可。
  • [root@hadoop001 shell]# cat helloworld.sh
    #!/bin/bash -x
    echo “www.ruozedata.com”
1、把bin/bash解释器删除,
[root@hadoop001 shell]# which sh
/bin/sh

2、使用/bin/sh执行:
[root@hadoop001 shell]# /bin/sh helloworld_nohead.sh
www.ruozedata.com

3、调试:
[root@hadoop001 shell]# sh -x helloworld_nohead.sh
+ echo www.ruozedata.com
www.ruozedata.com

总结:
1、开头定义:#/bin/bash
2、 sh -x xxx.sh

如果第一行#!/bin/bash -x,这样会影响结果查看,建议使用sh -x;sh是万能的:

[root@hadoop001 shell]# chmod 644 helloworld.sh
[root@hadoop001 shell]# ll
total 8
-rw-r-xr-- 1 root root 26 Apr 12 15:08 helloworld_nohead.sh
-rw-r--r-- 1 root root 40 Apr 12 14:57 helloworld.sh
[root@hadoop001 shell]# sh helloworld.sh
www.ruozedata.com
[root@hadoop001 shell]# ./helloworld.sh
-bash: ./helloworld.sh: Permission denied

1.1、定义变量和使用

1、静态变量:k=v	k="v"	数值和字符串的定义

2、动态变量:k=`v`,v是指linux的命令,定义动态变量的时候等号前后不能有空格

3、引用:$k、${k},只有我们在引用的时候才需要加上$
[root@hadoop001 shell]# cat variable.sh
#!/bin/bash
rz='www.ruozedata.com'
date=`date`
echo $rz
echo $date
1、定义变量,引用变量
[root@hadoop001 shell]# cat variable.sh
#!/bin/bash
rz='www.ruozedata.com'
date=`date`
echo $rz
echo $dateecho $rzjepson
echo ${rz}jepson

2、结果如下
[root@hadoop001 shell]# sh variable.sh
www.ruozedata.com
Sun Apr 12 15:38:48 CST 2020

www.ruozedata.comjepson

总结:
1、=前后不能有空格
2、字符串建议大家使用双引号
3、引用变量加上{}

1.2、传递参数

第一步:

1、编辑传参脚本:
vi parameter.sh

[root@hadoop001 shell]# cat parameter.sh
#!/bin/bash
echo $1
echo $2

2、使用Shell脚本的时候传入a b两个参数:
[root@hadoop001 shell]# sh parameter.sh a b
a
b

第二步:

[root@hadoop001 shell]# cat parameter.sh
#!/bin/bash
echo $1
echo $2

echo "个数:$#"

echo "传递参数作为1个字符串显示:$*"

echo "PID:$$"

[root@hadoop001 shell]# sh parameter.sh "john" "sail"
john
sail
个数:2
传递参数作为1个字符串显示:john sail
PID:21458
  • 生产上会把pid写到文件中

1.3、一维数组

1、vi array.sh
[root@hadoop001 shell]# cat array.sh
#!/bin/bash

arr=(ruoze jepson sail john)
//打印所有个数
echo ${arr[*]}
//打印数组中的第一、第二、第三个数
echo ${arr[0]} ${arr[1]} ${arr[2]}
//打印数组中的个数
echo ${#arr[*]}

2、执行这个array.sh
[root@hadoop001 shell]# sh array.sh
ruoze jepson sail john
ruoze jepson sail
4

//数组中的*号也可以用@符号进行替换:

1.4、if判断

1、编辑if.sh
[root@hadoop001 shell]# cat if.sh
#!/bin/bash

a="abc"
b="jepson"

if [ $a == $b ];then
echo "=="
else
echo "!="
fi

//注意:中括号前后各要加一个空格,==前后也要加一个空格
2、使用sh来执行if.sh:
[root@hadoop001 shell]# sh if.sh
!=

3、进入debug调试模式:
[root@hadoop001 shell]# sh -x if.sh
+ a=abc
+ b=jepson
+ '[' abc == jepson ']'
+ echo '!='
!=

if的shell脚本中有多层判断怎么办?

[root@hadoop001 shell]# cat if.sh
#!/bin/bash

a="ccc"
b="jepson"

if [ "$a" == "$b" ]
then
echo "=="

elif [ "$a" == "ccc" ]
then
echo "ccc"
else
echo "!="
fi

1.5、循环

  • for循环:
1、for循环语句如下:
[root@hadoop001 shell]# cat forwhile.sh
#!/bin/bash

for x in 1 2 3 4 5
do
echo $x
done

echo "----这是一条分割线----"

for ((i=1;i<10;i++))
do
echo $i
done

echo "----这是一条分割线----"

j=1
while(($j<6))
do
echo $j
let j++
done
  • 分割字符串:

vi split.sh

1、有两种方法来把数组拆分:
[root@hadoop001 shell]# cat split.sh
#!/bin/bash

s="rz,jespon,sail,john,fox,tom,abner"

OLD_IFS="$IFS"
IFS=","
arr=($s)
IFS="$OLD_IFS"

for x in ${arr[*]}
do
echo $x
done

echo "----这是一条分割线----"

arr2=(${s//,/ })
for x in ${arr[*]}
do
echo $x
done

//运行结果输出:
[root@hadoop001 shell]# sh split.sh
rz
jespon
sail
john
fox
tom
abner
----这是一条分割线----
rz
jespon
sail
john
fox
tom
abner

1.6、监控脚本

场景:多台机器,大数据测试环境是在公司机房,局域网,存在网络波动,VM物理机器挂了(断电)、VM虚拟机挂了

正常情况写一个脚本用来ping 机器 --> ssh机器,正常监控公司大数据的机器Zabbix(需要每台机器安装软件,占据资源)

CDH上自带也有监控,但是它自带的比较慢:

[root@hadoop001 shell]# cat ping.sh
#!/bin/bash

for ip in $(cat /opt/shell/ip_list|sed "/^#/d")
do
ping -c 1 $ip &>/dev/null
a=$?
sleep 2
ping -c 1 $ip &>/dev/null
b=$?
sleep 2
ping -c 1 $ip &>/dev/null
c=$?
sleep 2
DATE=$(date +%F" "%H:%M)
if [ $a -ne 0 -a $b -ne 0 -a $c -ne 0 ];then
echo "Critical: ${ip} can't ping"

else
echo "${ip} ping is successfully"

fi
done

//学会利用for循环,符合条件就发,不符合条件不发
[root@hadoop001 shell]# sh ping.sh
182.61.200.6 ping is successfully
Critical: 125.210.74.170 can't ping
Critical: 113.215.232.232 can't ping
47.98.238.163 ping is successfully
144.34.179.161 ping is successfully

vi ssh.sh

[root@hadoop001 shell]# cat ssh.sh
#!/bin/bash

#ip_list还是需要当前路径下的文件
for ip in $(cat /opt/shell/ip_list|sed "/^#/d")

do
#ssh能够返回date,说明服务器正常
ssh -o ConnectionTimeout=5 $ip date &>/dev/null

a=$?

if [ $a -ne 0 ];then
echo "ssh ${ip} checking is failed"
else
echo "ssh ${ip} checking is successfully"
fi
done

需求:每个ip的分隔不是以换行符来的,而是以逗号来进行分割,我们应该如何操作呢?

1.7、维护脚本

ssh脚本,需要提前部署好多台机器的信任关系
场景:大数据多台机器,Phoenix jar,改造Phoenix,jar升级;通过中心机器1台:–> 多台机器,
scp 传输文件到其它机器(前提就是多台机器间的信任关系)。

  • 新版本jar替换旧版本jar包的shell命令:
HOSTNAME_LIST="001,002,003,004"
JAR=phoenix-4.10.0-cdh5.16.2-server.jar
SOURCEPATH=/opt/sync/jars
TARGETPATH=/opt/cloudera/parcels/CDH/lib/hbase/lib

OLD_IFS="$IFS"
IFS=","
arr=($HOSTNAME_LIST)
IFS="$OLD_IFS"

for hostname in ${arr[@]}
do
echo "hadoop$hostname:"

ssh "hadoop$hostanme" "mv $TARGETPATH/$JAR"
scp $SOURCEPATH/$JAR "hadoop$hostname":$TARGETPATH/$JAR
ssh "hadoop$hostname" "ls -l $TARGETPATH/$JAR"
done

//如果机器名不是这么有规则的,补全机器名称即可

二、作业

Shell脚本中if留的作业:

1、if判断 数值 字符串 判断文件是否存在 文件是否为空

  • 点赞
  • 收藏
  • 分享
  • 文章举报
Spark on yarn 发布了28 篇原创文章 · 获赞 0 · 访问量 949 私信 关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: