Linux shell 脚本基础介绍

介绍

shell 脚本是实现 Linux 系统自动化的重要工具,提高效率,避免重复劳动,例如如下场景
1、系统安装完后的优化、IP地址设置
2、系统安装完后服务的搭建
3、系统资源、服务的监控等

学习 shell 脚本最好有以下基础
1、Linux 中常用的命令
2、常见的服务和搭建、排除、优化,nginx、nfs等等
3、vim/vi 文本编辑器,grep sed awk

内容

1、变量
2、判断语句:ifcase
3、循环语句:forwhile4、函数
5、流程控制语句:continuebreak、exit
等等

什么是 shell 脚本

最简单的 shell 脚本就是命令的堆砌
严格的 shell 脚本会包含有命令、判断语句、循环语句、流程控制语句、变量、注释信息等等。

例子

现在要编写一个脚本清除日志,日志为 /access.log
root@test:/home/test# echo 123 > /access.log
root@test:/home/test# cat /access.log 
123
root@test:/home/test# vim clean_log.sh
cd /
>/access.log
echo "日志清除完成"
root@test:/home/test# sh clean_log.sh 
日志清除完成
root@kunjuee:/home/test# cat /access.log 

上面的脚步是不规范的

#!/bin/bash
DIR=/
ROOT_UID=0
#只有root用户才能清除日志
if ["$UID" -ne "$ROOT_UID"]
then
 echo "只有root用户才能清除日志"
 exit 1
fi

cd $DIR || {
echo "切换目录失败"
exit 2
}
>access.log && echo "清除日志成功"

介绍

#!/bin/bash
第一行一般来说用于指定命令解释器, sh script-name
脚本执行方式:
    1. sh scripts-name 或 /bin/bash scripts-name 脚步文件可以没有可执行权限
    2. /path/scripts-name 命令全路径,或者相对路径,必须要有可执行权限
    3. source /path/scripts-name 或 ./path/scripts-name 能够让脚本中的变量与函数在脚本执行完成后依然生效。
# 查看默认的命令解释器
root@test:~$ echo $SHELL
/bin/bash

在shell脚本中只要以 # 开头,表示注释
一般来说脚本名称会以.sh结尾,但这不是必须的

shell 脚本是按行执行的,并且默认情况下可以没有缩进,但是为了代码的易读性,所以人为的添加缩进

变量

在 shell 中有三种变量:环境变量,自定义全局变量、自定义局部变量
变量名可以由字母(大小写)、数字、下划线等组成,不能以数字开头

环境变量,例如$SHELL,$UID 等,一般可以在 /etc/profile 或 /etc/bashrc等文件中看到

全局变量:export 变量名=value
能够对子 shell 生效

局部变量:变量名=value
定义完后只能当前shell生效

测试

$ aaa=123
$ export bbb=456
$ echo aaa
123
$ echo bbb
456
# 查看当前shell进程号
$ echo $$
12866
# 开启一个子shell
$ bash
$ echo $$
16990
$ echo $aaa

$ echo $bbb
456
$ exit
除了上面的变量外还有一些特殊功能的变量,$0 $? $n $#

$0:脚本名称
$?:上一条命令的执行结果
$n:n就是第几个参数,脚本传参功能
$#:参数的个数

除了以上功能,还有条件测试表达式、文件测试表达式、字符串测试表达式等等,man bash 来进行查看

判断语句 if

if 语句分为单分支语句、双分支语句、多分支语句,并且 if 语句是可以互相嵌套的。
  • 单分支语句格式:

    if <条件表达式>
    then
      指令1
      ...
    fi
  • 双分支语句格式:

    if <条件表达式>
    then
      指令1
      ...
    else
      指令2
      ...
    fi
  • 多分支语句格式:

    if <条件表达式>
    then
      指令1
      ...
    elif <条件表达式>
    then
      指令2
      ...
    elif <条件表达式>
    then
      ...
    else
      指令3
      ...
    fi
    <条件表达式>,这里的条件表达式可以是命令,test [] [[]] (())

测试

现在编写一个脚本,判断某个服务是否运行,如果已经运行则提示服务已经运行并退出,如果没有运行则运行,如果没有安装服务,则先进行安装再运行,在安装前将yum源设置为阿里云的yum源
# grep 是聚合草足,wc -l 是统计数量
$ jps -l | grep file | wc -l
# 查看服务是否已经启动
$ systemctl is-active mysql
# 查看上一条命令是否执行成功
$ echo $?
# 
$ ss -lntup
#!/bin/bash

if[$# -eq 1]
then
 #判断服务是否安装
 #rmp -qa | grep $1 | wc -l
 aa=`rpm -qa $1|wc -l`
 if[$aa -lt 1]
 then
  #下载阿里云镜像源
  curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
  if [ $? -eq 0]
  then
   #安装服务
   yum install -y $1
   systemctl start $1
   systemctl enable $1
   bb=`systemctl is-active $1`
   if [ $bb == 'active']
   then
    echo "${1}服务安装并启动成功"
   else
    echo "${1}服务安装失败,请检查"
   fi
  else
   echo "安装yum源失败,请检查网络"
   exit 1
  fi
 else
  cc=`systemctl is-active $1`
  if [ $cc == "active" ]
  then
   echo "${1}服务已经开启"
  else
   systemctl start $1
   if [$? -eq 0 ]
   then
    echo "${1}服务已经启动成功"
   else
    echo "${1}服务启动失败,检查配置是否正常"
   fi
   systemctl enable $1
  fi
 fi
else
 echo "请输入要运行的服务,格式为:if.sh 服务名称"
fi

for 循环

for 循环与 while 循环最大的区别在于循环的次数,一般来说 for 循环用于有限次数的循环,while 循环一般来说用于守护进程。

格式

for 变量名 in 变量取值表
do
 指令
 ...
done
例子:
现在有几个 KVM 虚拟机,配置文件是以 xml 结尾的文件,文件中记录着虚拟机的各种信息。现在需要获取虚拟机的名称与磁盘的对应关系,并且以空格分隔。
# 打印 xml 的第九行,| 将前面的结果丢给后面的命令,awk进行列输出,-F 指定分隔符,
$ sed -n 9p centos7-11.xml | awk -F "[<>]" '{print $3}'
#!/bin/bash
file_name=`ls /root/centos7-*.xml`
for n in $file_name
do
 kvm_name=`sed -n 9p $n | awk -F "[<>]" '{print $3}' `
 disk_name=`sed -n 41p $n | awk -F "'" '{print $2}'`
 echo "${n}:${kvm_name} ${disk_name}"

while 循环语句

格式

while 条件表达式(true)一直执行
do
 指令
done
例子:
猜随机数,系统随机生成一个160之间的数字,用户来猜这个数字,对用户输入的数字进行判断,如果不等于则提示大或小,正确后提示正确,并提示尝试次数。
# 生成随机数 0~32768 之间
$ echo $RANDOM
$ expr 1 + 1
2
$ echo $?
0
$ expr aa + 1
expr:非整数参数
$ echo $?
2
#!/bin/bash

try=0
num=$((RANDOM%61))

one(){
 # read 是交互式的
 read -p "please input a num 0 ~ 60:" a

 # 判断输入的是否为数字
 expr $a + 1 & > /dev/null
 if [ $? -ne 0 ]
 then
  echo "请输入正确的内容"
  one
fi
}

two(){
 ((try++))
 if [ $a -eq $num ]
 then
  echo "猜对了,数字为:${num}.尝试次数为${try}"
  exit 0
 elif [ $a -gt $num ]
 then
  echo "大了,请重试"
  one
 else
  echo "小了,请重试"
  one
 fi
}

three(){
 one
 while true
  do
 two
 done
}
three
本作品采用《CC 协议》,转载必须注明作者和本文链接
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!
未填写
文章
247
粉丝
18
喜欢
217
收藏
62
排名:731
访问:9753
私信
所有博文
社区赞助商