新手注意: 以下是我对新手的告诫
# .sh 表示是shell脚本文件,属于约定俗成的习惯问题 ,虽然不写也能使用,但很长时间后,你都不知到哪个是脚本 ,哪个是文档,直接弄混,因此,最好养成良好习惯,
# 文件名的后 缀带.sh
# 写注释注意 文字与“#” 号 中间空格,为了美观和方便,无论是shell,Java,还是python。
# 不然,某时候,你的同事可能会认为你是野路子,非科班出身,偶尔也许还会鄙视一二。
# 你的注释要尽量格式化
我的shell脚本注释如下
# !/bin/bash
# date:2024/8/5
#
#
# ##:lqh
#
# ping主机测试
关于注释的格式,以我个人举例
关于注释的解释:
#!/bin/bash
是一个 shebang 行,用于指定脚本的解释器,这里指定使用 Bash 解释器来执行脚本。
# date:2024/8/5
是对脚本的一个简短注释,说明了脚本的编写日期。# 第三行留着写 邮箱地址 练习方式等,如果公司需要就写,不需要就空着
# 第四行写作者名字,以便于脚本修订,优化或重构时公司可以精确定位到个人,按需写。
# 第五,六,七行则用简短凝练的几句话,叙述这个脚本的名字以及作用,还有一些其他的细节
# 一个脚本大部分情况下100行以内 ,shell的目的是:轻松,简短方便,自动化,如果过于
# 臃肿可能会背离初衷,建议python+shell 嵌套使用,或直接用python脚本
# 还是哪句话:你要让人相信你是一名靠谱的正规科班的程序员,而不是填鸭式教育出身。
写shell脚本的前期准备
shellcheck
shellcheck是用来检查shell脚本的工具,采用haskell语言开发的
在Debian-ubuntu体系中,可以直接采用apt install shellcheck安装完成;
在红帽-Centos体系中,yum是没有shellcheck的包的 会提示找不到包,因此,需要另一种方法安装。Centos安装shellcheck
由于shellcheck是haskell语言开发的,因此,先安装haskell语言的包管理工具 cabal-install
[root@s2 yum.repos.d]# yum install cabal-install
然后,就可以使用cabal install 来安装一些yum没有的诸如shellcheck 的包了注意,以下指令都会安装在~/.cabal/bin目录下
[root@s2 yum.repos.d]# cabal update
Downloading the latest package list from hackage.haskell.org
[root@s2 yum.repos.d]# cabal install cabal --reinstall # 清理缓存
cabal install cabal # 安装cabal 源仓库
cabal install shellcheck # 安装shellcheck
cabal install cabal的意思是:安装必要的cabal库,不安装,安装shellcheck时会报错在命令行中使用 : yum install ShellCheck -y
shellcheck yourscript.sh
当然还有其他方法:如下
在网页上使用
在网页 https://www.shellcheck.net 上,贴入你的脚本,运行检查即可
集成到编辑器中(推荐)
Vim 通过 ALE, Neomake 或 Syntastic 进行集成
Emacs 通过 Flycheck 或 Flymake 集成
Sublime 通过 SublimeLinter.
Atom 通过 Linter.
VSCode 通过 vscode-shellcheck.
集成到Sublime :强烈推荐,我现在在用 Sublime txt 这个软件码字 很轻量级
我会单出一个专题来讲这个软件,请关注后续。。。。
sublime :安装SublimeLinter --》tool 输入Install --》package install 输入SublimeLinter 安装
关闭sublime,重新打开,打开脚本文件。
tool --》输入SublimeLinter ,选择SublimeLinter :lint this view
如果没有SublimeLinter 就给根据以下内容安装插件 ,
SublimeLinter是一个Sublime Text的插件,它可以在你编写代码的时候,就提示出可能存在的语法错误。这样可以在代码编译或执行时,才发现错误,从而提高开发效率。
在Sublime Text中安装SublimeLinter的步骤如下:
打开Sublime Text。
按下
Ctrl+Shift+P
(或Cmd+Shift+P
on Mac)打开命令面板。输入
Install Package
,并选择它。在列表中找到
SublimeLinter
,并选择它进行安装。如果你想要SublimeLinter支持特定的语言,你还需要安装相应的SublimeLinter插件。例如,如果你想要支持Python代码的语法检查,你还需要安装
SublimeLinter-pylint
。安装步骤类似上述的SublimeLinter
安装步骤。注意:SublimeLinter需要Python环境支持,因此你的系统需要安装Python。
以下是在Sublime Text中安装
SublimeLinter-pylint
的示例步骤:
打开Sublime Text。
按下
Ctrl+Shift+P
(或Cmd+Shift+P
on Mac)打开命令面板。输入
Install Package
,并选择它。在列表中找到
SublimeLinter-pylint
,并选择它进行安装。安装完成后,SublimeLinter将在你编写代码时,使用
pylint
来提示Python代码中的语法错误。
windows上命令行使用
安装exe版本的之后,需要设置环境变量:
设置==》系统信息==》高级系统设置==》(最底下)环境变量设置==》系统变量->新建 path增加shellcheck.exe的所在路径。
关闭cmd窗口,重新打开,输入path,可以看到新增加的路径
cmd中输入shellcheck ,会出现回显
脚本01:网工常用的
脚本01:网工常用的
脚本用法: ping完后 把已经使用ip的归纳汇总到/opt/ip_up.txt,未使用的则/opt/ip_down.txt ,并统计未使用可用和已使用现在不能用中的IP个数,然后运维们在配静态IP的时候,从收藏的ip本(我这个案例中的ip本文件 是/opt/ipz_down.txt)找能用的IP给要配的主机配上)
[root@s2 opt]# vim l1-1.sh
[root@s2 opt]# chmod +x l1.sh
[root@s2 opt]# ./l1-1.sh # 执行脚本结果如下:
vim 里面的内容使用cat查看
# cat 文件名 查看文件内容
# 脚本名首字母,是L的小写 不是管道符[root@s2 opt]# cat l1-1.sh
# !/bin/bash
# date:2024/8/5
#
# ##:lwh
#
# ping主机测试,测试多个 ping完后 归纳未使用可用和已使用现在不能用中的IP并统计个 # 数,然后配静态IP的时候,从收藏的ip本找能用的IP给要配的主机配上ip_prefix=192.168.28
up_count=0 # 用于计数IP被使用的
down_count=0 # 用于计数IP未被使用的for i in {1..10}
do
if ping -c1 ${ip_prefix}.$i &>/dev/null; then
echo ${ip_prefix}.$i >> /opt/ip_up.txt
((up_count++)) # 每次成功ping后,计数变量增加1
echo "IP已被使用:${ip_prefix}.$i"
else
echo ${ip_prefix}.$i >> /opt/ip_down.txt
((down_count++)) # 每次未成功ping后,计数变量增加1
echo "IP未使用:${ip_prefix}.$i"
fi
doneecho "IP已被使用一共:$up_count" # 输出IP被使用的总数
echo "IP未被使用一共:$down_count" # 输出IP未被使用的总数
脚本02
脚本02:
[root@s2 opt]# ls
ca-config.json ca-key.pem etcd ip_down.txt l1.s
ca.csr ca.pem etcd-v3.2.12-linux-amd64 ip_up.txt rh
ca-csr.json containerd etcd-v3.2.12-linux-amd64.tar.gz l1-1.sh serv
[root@s2 opt]# vim l2-2.sh
[root@s2 opt]# chmod +x l2-2.sh
[root@s2 opt]# ./l2-2.sh
请输入用户名:root
用户名已存在
[root@s2 opt]# ./l2-2.sh
请输入用户名:jack
请输入密码:
更改用户 jack 的密码 。
新的 密码:无效的密码: 密码少于 8 个字符
重新输入新的 密码:passwd:所有的身份验证令牌已经成功更新。
用户创建成功
[root@s2 opt]# cat l2-2.sh # 查看脚本内容
#!/bin/bash
# date:2024/8/05
#
###:lwh
#
# 用于判断用户是否存在,如果不存在则创建用户并设置密码
# 为了执行 useradd 和 passwd 命令,可能需要具有特定的权限(比如 root 权限)
# 因此,如 果脚本中涉及到需要特权的命令,可能需要以特权用户或通过 sudo 执行# 提示用户输入用户名
read -p "请输入用户名:" username# 检查用户是否存在
if id "$username" &>/dev/null; then
echo "用户名已存在"
else
# 提示用户输入密码
read -s -p "请输入密码:" password
echo# 创建用户并设置密码
sudo useradd -m $username
echo -e "$password\n$password" | sudo passwd $username
echo "用户创建成功"
fi
脚本 03 :判断当前linux系统内核版本 两种方式,
如下:
第一种
第一种
[root@s2 opt]# vim l3.sh
[root@s2 opt]# chmod +x l3.sh
[root@s2 opt]# ./l3.sh
内核是3
次版本大于10
[root@s2 opt]# cat l3.sh
#!/bin/bash
# date:2024/8/05
#
###:lwh
#
# 判断当前linux系统内核主版本是否为3,且次版本是否大于10
num1=`uname -r|awk -F"." '{print $1}'`
num2=`uname -r|awk -F"." '{print $2}'`
if [[ $num1 == 3 ]];then
echo " 内核是3"
else
echo "内核不是 3"
fiif [[ $num2 == 10 ]];then
echo "次版本大于10"
else
echo "次版本没有大于 10"
fi
[root@s2 opt]#
第二种
[root@s2 opt]# vim l3-3.sh
[root@s2 opt]# chmod +x l3-3.sh
[root@s2 opt]# ./l3
l3-3.sh l3.sh
[root@s2 opt]# ./l3-3.sh
当前内核主版本不为3,小版本小于等于10
[root@s2 opt]# cat l3-3.sh#!/bin/bash
# date:2024/8/05
#
# ##:lwh
# kernel_version译为:内核版本 major_version译为:主要版本
# mior_version译为:小版本
# 判断当前linux系统内核主版本是否为3,且次版本是否大于10# 获取当前内核版本
kernel_version=$(uname -r)# 提取主版本号和次版本号
major_version=$(echo $kernel_version | cut -d. -f1)
minor_version=$(echo $kernel_version | cut -d. -f2)# 判断内核主版本是否为3,且次版本是否大于10
if [ $major_version -eq 3 ] && [ $minor_version -gt 10 ]; then
echo "当前内核主版本为3,次版本大于10"
else
echo "当前内核主版本不为3,小版本小于等于10"
fi
[root@s2 opt]#
脚本04
01:yum 源可用
# 判断vsftpd软件包是否安装,如果没有则自动安装 (yum是否能用,不能用自动修复, 重新配置yum源,重新自动执行安装,测试是否安装成功安装) 定义重新执行安装脚本的最大次数
脚本04
[root@s2 opt]# vim l4.sh
[root@s2 opt]# chmod +x l4.sh
[root@s2 opt]# ./l4.sh sh
已加载插件:fastestmirror, langpacks
........
正在解决依赖关系
--> 正在检查事务
...........安装过程省略......正在安装 : vsftpd-3.0.2-29.el7_9.x86_64 1/1
验证中 : vsftpd-3.0.2-29.el7_9.x86_64 1/1已安装:
vsftpd.x86_64 0:3.0.2-29.el7_9完毕!
vsftpd 软件包安装成功 # 这个是脚本测试输出结果
[root@s2 opt]# cat l4.sh # 查看脚本内容
# !/bin/bash
# date:2024/8/5
#
# ##:lwh
# 判断vsftpd软件包是否安装,如果没有则自动安装 (yum是否能用,不能用自动修复
# 重新配置yum源,重新自动执行安装,测试是否安装成功安装)# 定义重新执行安装脚本的最大次数
max_retry=2
retry_count=0while true; do
# 检查vsftpd软件包是否已安装
if rpm -q vsftpd &>/dev/null; then
echo "vsftpd 软件包已安装"
break
else
# 尝试安装vsftpd软件包
sudo yum install -y vsftpdif [ $? -ne 0 ]; then
# 如果安装失败,尝试安装ntp软件包测试yum源是否可用
sudo yum install -y ntpif [ $? -eq 0 ]; then
echo "yum 源可用,请排查其他错误"
# 安装vim命令
sudo yum install -y vimif [ $? -eq 0 ]; then
echo "vim 命令安装成功"
# 移除ntp软件包
sudo yum remove -y ntp
echo "yum 源可用,请排查其他错误"
break
else
echo "vim 命令安装失败,重新配置yum源"
((retry_count++))if [ $retry_count -le $max_retry ]; then
echo "第 $retry_count 次尝试重新配置yum源"
# 备份原有yum源
sudo mkdir -p /etc/yum.repos.d/repo.bak
sudo mv /etc/yum.repos.d/* /etc/yum.repos.d/repo.bak/
# 下载新的yum源
sudo wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
sudo wget -O /etc/yum.repos.d/epel.repo https://mirrors.aliyun.com/repo/epel-7.repo
# 清理并重新生成yum源
sudo yum clean all
sudo yum makecache
else
echo "已达到最大重试次数,无法重新配置yum源"
break
fi
fi
else
echo "yum 源不可用,重新配置yum源"
# 备份原有yum源
sudo mkdir -p /etc/yum.repos.d/repo.bak
sudo mv /etc/yum.repos.d/* /etc/yum.repos.d/repo.bak/
# 下载新的yum源
sudo wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
sudo wget -O /etc/yum.repos.d/epel.repo https://mirrors.aliyun.com/repo/epel-7.repo
# 清理并重新生成yum源
sudo yum clean all
sudo yum makecache
fi
else
echo "vsftpd 软件包安装成功"
break
fi
fi
done
[root@s2 opt]#
02:在yum源不可用情况下
我个人常用的 本人已测试
# 判断vsftpd软件包是否安装,如果没有则自动安装 (yum是否能用,不能用自动修复, 重新配置yum源,重新自动执行安装,测试是否安装成功安装) 定义重新执行安装脚本的最大次数
[root@s1 yum.repos.d]# ls # 为了满足实验环境,我本来基础源删掉 # 剩下几个指定安装包源
backup mysql-community.repo nginx.repo
mysql-community-debuginfo.repo mysql-community-source.repo repobak
[root@s1 ~]# vim l4.sh
[root@s1 ~]# chmod +x l4.sh
[root@s1 ~]# vim l4.sh
[root@s1 ~]# ./l4.sh
已加载插件:fastestmirror, langpacks
。。。。报错如下,它会自动修复yum 源重新执行安装。。。。。
ile contains parsing errors: file:///etc/yum.repos.d/nginx.repo
[line 2]: name=nginx stable repo
[line 3]: baseurl=http://nginx.org/packages/centos///
[line 4]: gpgcheck=1
[line 5]: enabled=1
[line 6]: gpgkey=https://nginx.org/keys/nginx_signing.key
[line 7]: module_hotfixes=true
[root@s1 opt]# cat l4-1.sh
# !/bin/bash
# date:2024/8/5
#
# ##:lwh
# 判断vsftpd软件包是否安装,如果没有则自动安装 (yum是否能用,不能用自动修复
# 重新配置yum源,安装yum源等待45分钟,配置好源系统会自动重新执行安装,测试是否安装成功安装)# 定义重新执行安装脚本的最大次数
max_retry=2
retry_count=0while true; do
# 检查vsftpd软件包是否已安装
if rpm -q vsftpd &>/dev/null; then
echo "vsftpd 软件包已安装"
break
else
# 尝试安装vsftpd软件包
sudo yum install -y vsftpdif [ $? -ne 0 ]; then
# 如果安装失败,尝试安装ntp软件包测试yum源是否可用
sudo yum install -y ntpif [ $? -eq 0 ]; then
echo "yum 源可用,请排查其他错误"
# 安装vim命令
sudo yum install -y vimif [ $? -eq 0 ]; then
echo "vim 命令安装成功"
# 移除ntp软件包
sudo yum remove -y ntp
echo "yum 源可用,请排查其他错误"
break
else
echo "vim 命令安装失败,重新配置yum源"
((retry_count++))if [ $retry_count -le $max_retry ]; then
echo "第 $retry_count 次尝试重新配置yum源"
# 备份原有yum源
sudo mkdir -p /etc/yum.repos.d/repo.bak
sudo mv /etc/yum.repos.d/* /etc/yum.repos.d/repo.bak/
# 下载新的yum源
sudo wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
sudo wget -O /etc/yum.repos.d/epel.repo https://mirrors.aliyun.com/repo/epel-7.repo
# 清理并重新生成yum源
sudo yum clean all
sudo yum makecache
echo "等待45分钟..."
sleep 2700 # 45分钟 = 45 * 60 = 2700秒
else
echo "已达到最大重试次数,无法重新配置yum源"
break
fi
fi
else
echo "yum 源不可用,重新配置yum源"
# 备份原有yum源
sudo mkdir -p /etc/yum.repos.d/repo.bak
sudo mv /etc/yum.repos.d/* /etc/yum.repos.d/repo.bak/
# 下载新的yum源
sudo wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
sudo wget -O /etc/yum.repos.d/epel.repo https://mirrors.aliyun.com/repo/epel-7.repo
# 清理并重新生成yum源
sudo yum clean all
sudo yum makecache
fi
else
echo "vsftpd 软件包安装成功"
break
fi
fi
done
[root@s1 yum.repos.d]# ls
CentOS-Base.repo epel.repo repo.bak
[root@s1 yum.repos.d]#
脚本05
[root@s2 opt]# vim l5.sh
[root@s2 opt]# chmod +x l5.sh
[root@s2 opt]# ./l5.sh
请输入软件名称:ntp
软件 ntp 正在运行
[root@s2 opt]# systemctl stop ntpd
[root@s2 opt]# ./l5.sh
请输入软件名称:ntp
软件 ntp 未运行[root@s2 opt]# cat ./l5.sh
# !/bin/bash
# date:2024/8/5
#
# ##:lwh
##
#允许用户在屏幕上输入软件名称,然后检查该软件是否正在Linux系统中运行# 提示用户输入软件名称
read -p "请输入软件名称:" software_name# 使用ps命令和grep来检查是否有该软件的进程在运行
if ps aux | grep -v grep | grep "$software_name" &> /dev/null; then
echo "软件 $software_name 正在运行"
else
echo "软件 $software_name 未运行"
fi
脚本06
01: 判断指定的主机是否能ping通,使用$1变量
[root@s2 opt]# vim l6.sh
[root@s2 opt]# chmod +x l6.sh[root@s2 opt]# ./l6.sh
请输入要检查的主机地址
[root@s2 opt]# ./l6.sh 192.168.28.7
192.168.28.7 可以ping通
[root@s2 opt]# cat ./l6.sh
# !/bin/bash
# date:2024/8/5
#
# ##:lwh
#
#
# 判断指定的主机是否能ping通,使用$1变量if [ -z "$1" ]; then
echo "请输入要检查的主机地址"
exit 1
fiping -c 1 $1 > /dev/null
if [ $? -eq 0 ]; then
echo "$1 可以ping通"
else
echo "$1 无法ping通"
fi
[root@s2 opt]#
02: 判断指定的主机是否能ping通,使用host变量,且与屏幕交互
[root@s2 opt]# vim l6-1.sh
[root@s2 opt]# chmod +x l6-1.sh
[root@s2 opt]# ./l6-1.sh
请输入要检查的主机地址:
192.168.28.7
192.168.28.7 可以ping通
[root@s2 opt]# cat l6-1.sh
# !/bin/bash
# date:2024/8/5
#
# ##:lwh
#
# 判断指定的主机是否能ping通,使用host变量,且与屏幕交互echo "请输入要检查的主机地址:"
read hostif [ -z "$host" ]; then
echo "未提供主机地址"
exit 1
fiping -c 3 $host > /dev/null
if [ $? -eq 0 ]; then
echo "$host 可以ping通"
else
echo "$host 无法ping通"
fi
[root@s2 opt]#
脚本07
[root@s2 opt]# vim l7.sh
[root@s2 opt]# chmod +x l7.sh
[root@s2 opt]# ./l7.sh
[root@s2 opt]# cat l7.sh
# !/bin/bash
# date:2024/8/5
#
# ##:lwh
#
## 定义阈值
disk_threshold=20
memory_threshold=80# 检查根分区剩余空间
root_usage=$(df / | awk 'NR==2 {print $5}' | cut -d'%' -f1)
if [ $root_usage -ge $disk_threshold ]; then
echo "根分区剩余空间不足 $disk_threshold% 警报" | mail -s "根分区剩余空间不足" xxxxxx@163.com
fi# 检查内存使用情况
memory_usage=$(free | awk 'NR==2 {print $3/$2 * 100}')
if [ $(printf "%.0f" $memory_usage) -ge $memory_threshold ]; then
echo "内存已使用超过 $memory_threshold% 警报" | mail -s "内存使用过高" xxxxxx@163.com
fi
注意:
# 脚本中的xxxxxx@163.com替换为实际的邮件接收地址
# 编辑crontab文件,添加定时任务每5分钟执行一次脚本
[root@s2 opt]# crontab -e
no crontab for root - using an empty one
crontab: installing new crontab
[root@s2 opt]# crontab -e
crontab: installing new crontab
[root@s2 opt]# crontab -l
*/5 * * * * /path/to/monitor.sh
[root@s2 opt]# crontab -r
[root@s2 opt]# crontab -l
no crontab for root
[root@s2 opt]#
expect交互式自动化和crontab定时计划任务的区别:
总的来说,expect 和 crontab 都是用于自动化任务管理的工具。expect 适用于交互式任务的自动化,而 crontab 适用于定时执行任务的自动化。两者用途不同,各自在不同的场景下发挥作用。
expect 和 crontab 可以结合使用。
在某些情况下,可能需要在特定的时间点执行一个交互式的任务,这时可以使用 expect 结合 crontab 实现。例如,假设您需要定时执行一个需要交互式输入的命令或脚本,您可以编写一个 expect 脚本来处理交互,然后将这个 expect 脚本放入 crontab 计划任务中,以便在指定的时间点自动执行。
实际上,结合使用 expect 和 crontab 可以实现更加复杂和灵活的自动化任务,既能处理交互式任务,又能按时执行指定的任务。这样可以更好地满足特定的自动化需求。
总的来说,expect 和 crontab 可以相互结合使用,以实现更灵活、全面的自动化任务管理。
expect 和 crontab 都是用于自动化任务管理的工具,但它们的功能和用途有所不同。
expect:expect 是一种用于自动化交互式任务的工具,,通常用于编写自动化脚本来模拟人与计算机之间的交互 (脚本执行到某个时候时需要人为的用键盘输入某些参数命令,expect则是模拟了键盘打字输入参数或命令这一步骤)它在通常用于处理需要用户输入和响应的任务,例如登录远程服务器、执行交互式命令行程序等。
expect 脚本可以编写逻辑来处理不同的交互情况,例如根据程序的不同提示输入不同的响应,从而实现自动化的交互过程。
一般来说,expect 脚本适合处理那些需要交互式输入的任务,而不适合简单的定时任务等。
crontab:crontab 是用于定时执行任务的工具,通常用于在指定的时间间隔或特定时间执行指定的命令或脚本。它是基于时间的任务调度工具。
通过编辑 crontab 文件,可以指定要运行的命令、脚本以及运行的时间,例如每天、每周、每月的某个特定时间点等。这使得用户能够轻松地自动执行重复性任务,而无需手动干预。
crontab 适合处理那些需要在固定时间点或时间间隔执行的任务,例如定期备份、定时数据清理、定时报表生成等。