开发实用Shell脚本

日常开发中,需要完成一些运维工作,需要编写Shell脚本提升自动化能力,提高效率。

1、文件批量重命名

案例描述:将指定目录下的所有.txt文件扩展名改为.yml

#!/bin/bash
# 批量重命名文件扩展名
directory=$1
for file in $directory/*.txt; do  
  mv "$file" "${file%.txt}.yml"
done
echo "当前目录下所有.txt文件已重命名为.yml"

使用方式:

./rename_files.sh /renamepath/to/directory

2、备份数据库

案例描述:每天凌晨自动备份MySQL数据库到指定目录。

#!/bin/bash
# 自动备份MySQL数据库
backup_dir="/backup/data/mysql"
db_user="root"
db_password="password"
db_name="mydatabase"
date_str=$(date +%Y%m%d%H%M%S)
backup_file="$backup_dir/$db_name-$date_str.sql"
mysqldump -u$db_user -p$db_password $db_name > $backup_file
echo "当前数据库$db_name已备份到$backup_file"

使用方式

在crontab -e中添加:0 0 * * * /path/to/backup_db.sh

3、查找并删除大文件

案例描述:查找并删除指定目录下大于100MB的文件。

#!/bin/bash
# 查找并删除大文件
directory=$1size_threshold=$((100 * 1024 * 1024))  
# 100MB in bytes
find $directory -type f -size +$size_threshold -exec rm -f {} \;
echo "已删除$directory目录下所有大于100MB的文件"

使用方法:

./delete_large_files.sh /path/to/directory

4、清理临时文件

案例描述:每天清理指定目录下的临时文件。

#!/bin/bash
# 清理临时文件
temp_dir="/tmp"
# 删除超过7天的临时文件
find $temp_dir -type f -mtime +7 -exec rm -f {} \;
echo "已清理$temp_dir目录下超过7天的临时文件"

使用方式:

在crontab -e中添加:0 0 * * * /path/to/cleanup_temp.sh

5、发送系统状态报告

案例描述:每天发送系统状态报告(如CPU、内存使用情况)到管理员邮箱。

#!/bin/bash
# 发送系统状态报告
email="service@example.com"
report=$(free -m && df -h && uptime && vmstat 1 5 | tail -n 15)
echo "$report" | mail -s "系统状态报告" $email

使用方式:

在crontab -e中添加:0 12 * * * /path/to/send_system_report.sh(假设每天上午12点发送)

6、检查磁盘空间并发送邮件

案例描述:当磁盘空间低于某个阈值时,发送邮件警告。

#!/bin/bash
# 检查磁盘空间并发送邮件
# 阈值百分比
threshold=80
email="service@example.com"
used=$(df / | grep / | awk '{ print $5}' | sed 's/%//g')
if [ $used -ge $threshold ]; then  
  echo "磁盘空间警告:已使用 $used%" | mail -s "磁盘空间警告" $email
fi

使用方式:

check_disk_threshold.sh

7、检测 MySQL 服务是否存活

案例描述:检查MySQL服务是否存活

#!/bin/bash
# 检测 MySQL 服务是否存活 
# host 为你需要检测的 MySQL 主机的 IP 地址,user 为 MySQL 账户名,passwd 为密码
# 这些信息需要根据实际情况修改后方可使用
host=XXX
user=XXX
passwd=XXX
mysqladmin -h '$host' -u '$user' -p'$passwd' ping &>/dev/null
if [ $? -eq 0 ]
then
       echo "MySQL is UP"
else
       echo "MySQL is down"
fi

8、Nginx访问日志自动按天(周、月)切割

#!/bin/bash
#nginx日志目录
LOG_DIR=/www/server/nginx/logs
#获取到上一天的时间
YESTERDAY_TIME=$(date -d "yesterday" +%F)
#归档日志取时间
LOG_MONTH_DIR=$LOG_DIR/$(date +"%Y-%m")
#归档日志的名称
LOG_FILE_LIST="access.log" 
for LOG_FILE in $LOG_FILE_LIST; do
   [ ! -d $LOG_MONTH_DIR ] && mkdir -p $LOG_MONTH_DIR
   mv $LOG_DIR/$LOG_FILE $LOG_MONTH_DIR/${LOG_FILE}_${YESTERDAY_TIME}
done
kill -USR1 $(cat $LOG_DIR/nginx.pid)

9、监控MySQL主从同步状态是否异常脚本

#!/bin/bash  
HOST=XX
USER=XX
PASSWD=XX
IO_SQL_STATUS=$(mysql -h$HOST -u$USER -p$PASSWD -e 'show slave status\G' 
2>/dev/null |awk '/Slave_.*_Running:/{print $1$2}')
for i in $IO_SQL_STATUS; do
   THREAD_STATUS_NAME=${i%:*}
   THREAD_STATUS=${i#*:}
   if [ "$THREAD_STATUS" != "Yes" ]; then
       echo "Error: MySQL Master-Slave $THREAD_STATUS_NAME status is 
$THREAD_STATUS!" |mail -s "Master-Slave Staus" xxx@163.com
   fi
done

10、监控特定进程是否存在 

#!/bin/bash

# 监控特定进程是否存在的脚本
process_name="nginx"  # 要监控的进程名

while true; do
    if pgrep -x "$process_name" > /dev/null; then
        echo "$process_name is running."
    else
        echo "$process_name is not running. Starting $process_name..."
        # 假设nginx的启动命令是service nginx start
        service $process_name start
    fi
    sleep 60  # 每60秒检查一次
done

11:限制特定用户进程数量 

#!/bin/bash 
 # 监控并重启崩溃服务的脚本 
 service_name="httpd"  # 要监控的服务名 
 while true; do     
    if service $service_name status > /dev/null 2>&1; then         
       echo "$service_name is running."     
    else         
       echo "$service_name has crashed. Restarting..."         
  # 重启服务         
    service $service_name restart     
  fi     
  sleep 60  # 每60秒检查一次 
 done

一、文件比较运算符

1. e filename 如果 filename存在,则为真 如: [ -e /var/log/syslog ] 
2. -d filename 如果 filename为目录,则为真 如: [ -d /tmp/mydir ] 
3. -f filename 如果 filename为常规文件,则为真 如: [ -f /usr/bin/grep ] 
4. -L filename 如果 filename为符号链接,则为真 如: [ -L /usr/bin/grep ] 
5. -r filename 如果 filename可读,则为真 如: [ -r /var/log/syslog ] 
6. -w filename 如果 filename可写,则为真 如: [ -w /var/mytmp.txt ] 
7. -x filename 如果 filename可执行,则为真 如: [ -L /usr/bin/grep ] 
8. filename1-nt filename2 如果 filename1比 filename2新,则为真 如: [ 
/tmp/install/etc/services -nt /etc/services ] 
9. filename1-ot filename2 如果 filename1比 filename2旧,则为真 如: [ 
/boot/bzImage -ot arch/i386/boot/bzImage ]

 二、字符串比较运算符

 1. -z string  如果 string长度为零,则为真 如:  [ -z "$myvar" ]
 2. -n string  如果 string长度非零,则为真  如: [ -n "$myvar" ]
 3. string1= string2  如果 string1与 string2相同,则为真 如:  ["$myvar" = "one two three"]
 4. string1!= string2  如果 string1与 string2不同,则为真 如:  ["$myvar" != "one two three"]

三、算术比较运算符 

 1. num1-eq num2  等于 如: [ 3 -eq $mynum ]
 2. num1-ne num2  不等于 如: [ 3 -ne $mynum ]
 3. num1-lt num2  小于 如: [ 3 -lt $mynum ]
 4. num1-le num2  小于或等于  如:[ 3 -le $mynum ]
 5. num1-gt num2  大于  如:[ 3 -gt $mynum ]
 6. num1-ge num2  大于或等于 如: [ 3 -ge $mynum ]

如何在Shell脚本中输出日志信息

1、方法1:使用echo命令打印日志

echo "This is a log message"

2、方法2:使用变量和echo命令打印日志

log_message="This is a log message"

echo $log_message

3、方式3:将日志输出到文件中

log_message="This is a log message"

log_file="log.txt"

echo $log_message >> $log_file

样例如下:

function loginfo() {     echo "[ INFO $(date '+%Y-%m-%d %H:%M:%S')] [ $1 ]" } 
 loginfo "Step1: aligning sequence data" sleep 5 # 等待5秒,避免两次loginfo的时间一样 
 loginfo "Step2: calling variants" 
 # 示例输出: # [ INFO 2024-11-08 19:22:15] [ Step1: aligning sequence data ] # [ INFO 2024-11-08 19:22:20] [ Step2: calling variants ]

RPM包常用

使用 rpm -qi 过滤安装日期

rpm -qi kernel | grep "Install Date"
# 输出示例:Install Date: Sun 10 Jul 2022 01:46:04 PM CST
基础安装命令格式
sudo rpm -ivh package_name.rpm  # 标准安装命令
‌-i‌:表示安装操作(install)14
‌-v‌:显示详细安装过程(verbose)14
‌-h‌:以 # 符号显示进度条(hash marks)45
关键选项
‌--test‌:
rpm -ivh --test package.rpm
‌--nodeps‌:
忽略依赖强制安装(可能导致软件无法运行
rpm -ivh --nodeps package.rpm
--force‌:
强制覆盖安装(即使已存在相同版本
rpm -ivh --force package.rpm
‌--replacepkgs‌:
重新安装已存在的包(修复文件丢失或损坏

典型安装场景如下:

标准安装‌:
sudo rpm -ivh httpd-2.4.6.rpm
输出进度条和详细日志
‌强制重装损坏包
sudo rpm -ivh --replacepkgs httpd-2.4.6.rpm
‌忽略依赖安装(紧急调试)‌
sudo rpm -ivh --nodeps mysql.rpm

卸载流程如下:

️基础卸载命令:
rpm -e <软件包名>  # 包名需完整(不含版本号和扩展名)
sudo rpm -e firefox-115.10.0-1.el7.x86_64  
核心选项如下:
--test(模拟卸载)‌:
检查依赖冲突但不实际删除,用于安全预检:
rpm -e --test package_name  
--nodeps(忽略依赖)‌:
‌强制卸载‌,无视其他软件包的依赖关系(高危操作):
rpm -e --nodeps corrupted_package  # 仅限紧急修复
‌--force(强制覆盖)‌:
通常与 --nodeps 联用,应对极端情况(如包损坏无法正常卸载):
rpm -e --force --nodeps package_name  
推荐卸载流程:
查询精准包名‌:
rpm -qa | grep httpd  # 输出示例:httpd-2.4.6-97.el7.x86_64
模拟卸载测试‌:
sudo rpm -e --test httpd-2.4.6-97.el7.x86_64
正式卸载‌:
sudo rpm -e httpd-2.4.6-97.el7.x86_64
‌反查文件所属包‌:
卸载前可通过文件路径定位包名:
rpm -qf /usr/bin/firefox  # 输出:firefox-115.10.0-1.el7.x86_64
‌查看卸载详情‌:
添加 -v 参数显示详细过程:
sudo rpm -ev package_name  

 

【附录Shell编程基础点】

1、Shell变量

1.1 用户自定义变量

 变量名 描述 示例  

USER_NAME 用户定义变量

USER_NAME="liyb"  

FILE_PATH 用户定义变量

FILE_PATH="/home/user/file.txt" 

 1.2 环境变量

变量名描述示例
HOME当前用户的家目录echo $HOME
PATH系统可执行文件路径echo $PATH
USER当前用户名echo $USER
SHELL当前使用的shell程序echo $SHELL
PWD当前工作目录echo $PWD
LANG系统的语言和地区设置echo $LANG
HOSTNAME当前主机名echo $HOSTNAME

1.3 特殊变量

变量名描述示例
$0脚本的名称echo $0 — 输出脚本文件名
2...脚本传递的参数echo 2 — 输出第一个和第二个参数
$#脚本传递的参数个数echo $# — 输出参数个数
$@所有传递给脚本的参数(保留空格)echo "$@" — 输出所有参数
$*所有传递给脚本的参数(作为一个字符串)echo "$*" — 输出所有参数(空格分隔)
$?上一个命令的退出状态码echo $?
$$当前脚本的进程 IDecho $$
$!最近在后台运行的命令的进程 IDecho $!

 1.4 数组变量

变量名描述示例
fruits定义一个数组变量fruits=("Apple" "Banana" "Cherry")
${fruits[0]}访问数组中的第一个元素echo ${fruits[0]}
${#fruits[@]}获取数组的长度echo ${#fruits[@]}
${fruits[@]}打印数组中的所有元素echo ${fruits[@]}

2、文件测试表达式

 [ <表达式> ]

操作符描述示例
-e检测文件是否存在[ -e file ]
-f检测是否为普通文件[ -f file ]
-d检测是否为目录[ -d directory ]
-L检测是否为符号链接[ -L link ]
-r检测文件是否可读[ -r file ]
-w检测文件是否可写[ -w file ]
-x检测文件是否可执行[ -x file ]
-s检测文件是否非空[ -s file ]
-z检测字符串是否为空[ -z string ]
-b检测是否为块设备[ -b file ]
操作符描述示例
-eq等于[ "b" ]
-ne不等于[ "b" ]
-lt小于[ "b" ]
-le小于或等于[ "b" ]
-gt大于[ "b" ]
-ge大于或等于[ "b" ]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大道之简

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值