Shell 脚本编程指南

说明

Shell 和 Shell 脚本的区别

Shell 指的是一种应用程序,常见的如 Windows 下的 CMD 窗口和 Linux 中的命令行窗口

Shell 脚本指的是为 Shell 编写的脚本程序

使用场景

因为在 Linux 集群下有配置与管理的需求,工作量比较大

所以使用 Shell 脚本处理同步配置文件、管理每一个节点等操作

属性

Shell 脚本编写流程

  1. 创建文件并添加执行权限

    创建以 .sh 为后缀结尾的脚本文件

1
2
3
4
5
6
# 通过 vi 或 vim 创建文件,只需要在创建完成并添加内容之后保存即可。
vi shell1.sh
vim shell2.sh

# 通过 touch 创建文件,可直接创建。
touch shell3.sh
为脚本添加执行权限

文件权限分为三种,分别为可读、可写、可执行(r w x),分别为 4 2 1

用户权限分为三种,分别为当前用户、同组用户、其他用户(u g o)
1
2
3
4
5
# 为当前用户赋予执行权限
chmod u+x shell1.sh

# 为当前用户、同组用户、其他用户赋予执行权限
chmod a+x shell2.sh
  1. 编写脚本头,声明解释器

    格式如下:

1
2
# 在第一行开头编写`
#!/bin/bash
  1. 编写脚本内容

  2. 添加注释,以 # 作为标识符

    写注释一方面规范代码,增强可阅读性

    在方便自己理解的同时也有利于整理思路

强制命令解析

1
2
3
4
5
6
7
8

# 在我们输入 echo pwd 的时候并不能显示当前所在目录的绝对路径,只是将 pwd 原样输出

# 如果想将当前目录原样输出可以 echo `pwd` 实现强制命令解析

# 强制命令解析符号为 ``

# 在 Shell 脚本编写时经常使用

获取变量的方式

1
2
3
4
5
6
7
# 在命令行和Shell脚本中正确获取变量的方式
echo $PATH
echo ${PATH}
echo "$PATH"

# 在命令行和Shell脚本中正错误取变量的方式
echo '$PATH'

参数的提取

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 和脚本配合使用,作为传入的参数

# 参数的个数
$#

# 第 n 个参数
$n

# 当前脚本(命令)名称
$0

# 取出所有参数
$@

# 参数左移
shift

方法

控制变色

1
2
3
4
5
# 设置前景色
tput setaf ColorNumber

# 设置背景色
tput setab ColorNumber

Shell 中比较运算符

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 相等  equal
if [ $i -eq 30 ]

# 不等 not equal
if [ $i -ne 30 ]

# 大于 greater than
if [ $i -gt 30 ]

# 小于 less than
if [ $i -lt 30 ]

# 大于等于 greater equal
if [ $i -ge 30 ]

# 小于等于 less equal
if [ $i -le 30 ]

if 判断语句

if 判断语句格式
1
if [ $i -lt | -gt | -eq | -ne | -ge | -le 10 ] ; then command ; elif .... then ...  ; else .... ; fi
小例子
1
2
3
4
5
6
7
8
#!/bin/bash

# 判断输入的参数 $1 的值小于30的话输出 young
# 判断输入的参数 $1 的值小于50的话输出 middle
# 判断输入的参数 $1 的值大于或等于50的话输出 old
# $1 为第一个参数

if [ $1 -lt 30 ] ; then echo young $# $@; elif [ $1 -lt 50 ] ; then echo middle ; else echo old ; fi

for 循环

for 循环语句格式
1
2
# for 循环语句格式
for (( exp1; exp2; exp3 )); do COMMANDS; done
循环打印 1-9
1
2
#!/bin/bash
for (( i=0; i<10; i++ )); do echo $i ; done
循环打印 9X9 乘法表
1
2
3
4
5
6
7
8
9
10
#!/bin/bash
for (( i=1; i<10; i++ )); do
for (( j=1; j<=i; j++ )); do
#tput setaf $j
# -ne 为不换行和转义
echo -ne "$j"x"$i"=$((j*i))'\t'
done
tput setaf $i
echo
done
1
2
3
4
5
6
for NAME [in WORDS ... ] ; do COMMANDS; done

# 通过对1.txt中的单词进行分割,取出所有单词并进行打印

#!/bin/bash
for x in `cat 1.txt` ; do echo $x ; done

while 循环

while 循环语句格式
1
2
# while 循环语句格式
while COMMANDS; do COMMANDS; done
while循环实现输出 1-9:
1
2
3
4
5
6
#!/bin/bash
i=1
while (( $i<10 )); do
echo $i
i=$((i+1))
done
while循环实现99乘法表:
1
2
3
4
5
6
7
8
9
10
11
#!/bin/bash
i=1
while (( $i<10 )); do
j=1
while (( $j<=$i )); do
echo -ne ${j}x${i}=$(( j*i ))'\t'
j=$((j+1))
done
i=$((i+1))
echo
done

case 语句

case 语句格式
1
2
# case 语句格式
case WORD in [PATTERN [| PATTERN]...) COMMANDS ;;]... esac
小例子
1
2
3
4
5
6
#!/bin/bash
case $1 in
helloworld | tom ) echo 1 ;;
hello ) echo 2 ;;
* ) echo 3 ;;
esac

Demo

自定义脚本的前提

在编写脚本完成之后先确定其权限,再将其上传到 /usr/local/bin 目录中

完成以上操作保证了在任意目录执行自定义脚本

xcall 批量操作脚本

前提是为每个节点安装和配置好ssh,使主节点能远程登陆其他节点
使用格式为: xcall.sh command
例如: xcall.sh yum install -y rsync
1
2
3
4
5
6
7
8
9
10
11
12
13
#!/bin/bash

# for循环
for((i=1 ; i<=5; i++)) ; do
# 更改文本颜色
tput setaf 2
# 输出以下文本
echo ==================== hadoop00$i $@ ===================
# 更改文本颜色
tput setaf 4
# ssh 远程登陆主机 hadoop$i ,执行输入的参数的命令
ssh hadoop00$i $@
done

xsync 同步脚本

从主节点同步配置文件到子节点
使用格式为: xsync.sh config_filename
例如: xsync.sh /app/software/hadoop/etc   
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#!/bin/bash

# 指出当前用户名
name=`whoami`
# 指定文件所在文件夹名称
dir=`dirname $1`
# 指定文件的文件名
filename=`basename $1`
# 进入到dir中
cd $dir
# 得到当前目录的绝对路径
fullpath=`pwd`

for((i=2 ; i<=5; i++)) ; do
tput setaf 2
echo ==================== hadoop00$i $@ ===================
tput setaf 9
# 远程同步命令 l 保留软连接 r 递归文件夹
rsync -lr $filename "$name"@hadoop00"$i":$fullpath
done
------ 本文结束------
如果对您有帮助的话请我喝瓶水吧!