10 个拿来就用的 Shell 脚本实例!

作者:JackTian

来源:公众号「杰哥的IT之旅」

ID:Jake_Internet

转载请联系授权(微信ID:Hc220088)

原文链接:10 个拿来就用的 Shell 脚本实例!

脚本 1 :该脚本用于读取Linux系统/etc/passwd文件中的所有/bin/bash作为登录默认Shell的用户列表,并提取每个用户的用户名。对于这些用户名进行检查,是否不等于roottidb。如果用户名不等于roottidb,则使用usermod命令对该用户的默认Shell修改为:/sbin/nologin,它通常用于禁止用户远程登录系统。

bash 复制代码
#!/bin/bash
for user in $(cat /etc/passwd | grep /bin/bash | cut -d ":" -f 1)
do
    if [ $user != "root" ] && [ $user != "tidb" ]; then
        usermod -s /sbin/nologin $user
    fi
done

脚本 2 :该脚本首先自定义了md5_listmd5_no_hash.txt两个文件,然后循环读取md5_list文件中每一行的哈希值,判断是否在md5_no_hash.txt文件中存在。

如果检查出哈希值在md5_no_hash.txt中存在,则打印信息:MD5值 xxx 在 md5_no_hash.txt 中存在

如果检查出哈希值在md5_no_hash.txt中不存在,则打印信息:MD5值 xxx 在 md5_no_hash.txt 中不存在

bash 复制代码
#!/bin/bash  

# 指定md5_list文件和md5_no_hash.txt文件的路径  
md5_list_file="md5_list"
md5_no_hash_file="md5_no_hash.txt"

# 循环读取md5_list文件中的每一行  
while IFS= read -r md5; do
    # 检查md5是否在md5_no_hash.txt中  
    if grep -q "$md5" "$md5_no_hash_file"; then
        echo "MD5值 $md5 在 $md5_no_hash_file 中存在"  
    else
        echo "MD5值 $md5 在 $md5_no_hash_file 中不存在"  
    fi
done < "$md5_list_file"

脚本 3 :该脚本的主要功能是:遍历读取一个包含IP地址的文件,如该文件名为:mmyd,然后对该文件里的每行IP地址执行ping操作,并检查丢包率。如果ping的丢包率为:100%,则输出该IP不可达的日志;如果ping不存在丢包率,则输出该IP可达的日志。

bash 复制代码
#!/bin/bash  
# author:JackTian
# 获取当前系统时间  
current_time=$(date +"%Y-%m-%d-%H:%M:%S")
# 获取开始时间戳  
start_time=$(date +%s)

for i in `cat mmyd`  # 这个是逐个读取该文件里的全部所列出的 IP 地址
do
  ping=`ping -c 10 $i | grep loss | awk '{print $6}' | awk -F "%" '{print $1}'`
  # 上面一行是对读出来的ip ping一次,看是否ping通。并取出loss的百分比的值 也就是丢包的值,看是否丢包
  Packet_Loss_Rate=`ping -c 10 $i | grep loss | awk '{print $6}'`

  if [ $ping -eq 100 ];then
  # 比较一下,看丢包的值是不是100,如果是100就是全部丢包,那就是没ping通,那就显示 IP ping 失败了,如果不等于100的话,就ping通了,就显示 IP ping 成功了。
    echo "$current_time 某某移动-活跃 IP 地址:$i ping 失败了,丢包率为:$Packet_Loss_Rate" >>/opt/jacktian/mmyd_ping.log
  else
    echo "$current_time 某某移动-活跃 IP 地址:$i ping 成功了!" >>/opt/jacktian/mmyd_ping.log
  fi
done

# 获取结束时间戳  
end_time=$(date +%s)

# 计算执行时间(秒)  
execution_time_seconds=$((end_time - start_time))

# 将执行时间转换为分钟和秒  
minutes=$((execution_time_seconds / 60))
seconds=$((execution_time_seconds % 60))

echo "执行完毕!该脚本执行时间共: $minutes 分钟 $seconds 秒"

脚本 4 :该脚本用于在Linux系统中创建新用户,并为该用户设置密码、省份代码、目录权限以及vsftpd服务的配置。

bash 复制代码
#!/bin/sh

read -p "user:" user
read -p "passd:" pass
read -p "province:" province

useradd $user -d /bigdata/sftp/province/$province/

#passwd $user
echo $pass | passwd --stdin $user

chown $user /bigdata/sftp/province/$province/ -R

chmod 750 /bigdata/sftp/province/$province/ -R

echo $user>>/etc/vsftpd/chroot_list

echo $user>>/etc/vsftpd/user_list

systemctl restart vsftpd.service
  • read -p "user:" user:提示用户输入一个用户名,并将输入的值存储在变量user
  • read -p "passd:" pass:提示用户输入一个密码,并将输入的值存储在变量pass中。注意:在输入密码时,不会显示任何字符
  • read -p "province:" province:提示用户输入一个省份代码,并将输入的值存储在变量province
  • useradd $user -d /bigdata/sftp/province/$province/:该命令将创建一个新用户,其用户名为之前输入的user,其家目录为:/bigdata/sftp/province/$province/
  • echo $pass | passwd --stdin $user:该命令会将之前输入的密码通过标准输入传给passwd命令,为新创建的用户设置密码
  • chown $user /bigdata/sftp/province/$province/ -R:该命令将更改新创建用户成为/bigdata/sftp/province/$province/目录及其子目录的所有者
  • chmod 750 /bigdata/sftp/province/$province/ -R:该命令会设置/bigdata/sftp/province/$province/目录及其子目录的权限为:750,也就是指:用户有读、写、执行的权限,而用户组只有读和执行的权限
  • echo $user>>/etc/vsftpd/chroot_list:该命令会将新创建的用户添加到vsftpd服务的chroot列表中。这表示当vsftpd服务在运行时,该用户会被限制在其自己的目录中,不能访问系统的其他目录
  • echo $user>>/etc/vsftpd/user_list:该命令会将新创建的用户添加到vsftpd服务的用户列表中。这表示当vsftpd服务在运行时,这个用户可以登录并访问系统。
  • systemctl restart vsftpd.service:重启vsftpd服务,使之前的所有配置生效

脚本 5 :该脚本用于在Linux系统中创建新用户,并为该用户设置密码、省份代码、idcid、目录权限以及vsftpd服务的配置。跟如上脚本 4 略有差异。

bash 复制代码
#!/bin/sh

read -p "user:" user
read -p "passd:" pass
read -p "province:" province
read -p "idcid:" idcid

mkdir -p /bigdata/sftp/province/$province/$idcid

useradd $user -d /bigdata/sftp/province/$province/$idcid

#passwd $user
echo $pass | passwd --stdin $user

chown $user /bigdata/sftp/province/$province/$idcid/ -R

chmod 750 /bigdata/sftp/province/$province/$idcid -R

echo $user>>/etc/vsftpd/chroot_list

echo $user>>/etc/vsftpd/user_list

systemctl restart vsftpd.service

脚本 6:该脚本首先自定义了省份编码列表为多个目录路径,循环遍历自定义的省份编码列表。对于每一个省份编码,脚本将其分割为三个部分:省份编码、运营商和数据上报类型。然后进入对应的省份目录。

执行du -sh 2023-10-* 命令,查询所有以2023-10-开头目录的大小,并将结果输出到一个名为$province_code_file_size.txt的文件中。

执行for循环,循环遍历所有子目录并查询每个子目录中的文件数量,然后将结果输出到一个名为$province_code_file_count.txt的文件中。

最后,脚本会返回到上级目录,以便对下一个省份编码下的文件大小及文件数量进行查询。所有的查询结果将保存在/opt/目录下的以省份编码命名的文件中。

bash 复制代码
#!/bin/bash  
# @Time    : 2023/10/30  
# @Author  : jacktian  
# @Desc    : 这是一个适用于某台服务器循环查询特定省份、特定运营商、特定数据上报类型的文件大小及文件个数的脚本。  
  
# 定义省份编码列表  
provinces=("110000/dianxin/1024" "120000/liantong/1024" "130000/yidong/1024")  
  
# 遍历省份编码列表  
for province in "${provinces[@]}"; do  
  
    # 分割省份编码、运营商和数据上报类型
    province_code=$(echo $province | cut -d'/' -f1)  
    operator=$(echo $province | cut -d'/' -f2)  
    category=$(echo $province | cut -d'/' -f3)  
  
    # 进入省份目录  
    cd /bigdata/sftp/province/$province_code/$operator/$category  
  
    # 执行du命令查询文件大小,并将结果输出到对应的省份编码txt文件  
    du -sh 2023-10-* >> /opt/"$province_code"_file_size.txt  
  
    # 执行for命令查询日期文件个数,并将结果输出到对应的省份编码txt文件  
    for date in $(ls -d */ | cut -d'/' -f1);  
        do  
            echo $date $(ls -1 $date | wc -l) >> /opt/"$province_code"_file_count.txt  
        done  
  
    # 返回上级目录  
    cd ..  
  
done

脚本 7:该脚本用于循环查询特定省份、特定数据上报类型的文件大小及文件个数。跟如上脚本 6 略有差异。

bash 复制代码
#!/bin/bash
# @Time    : 2023/10/30
# @Author  : jacktian
# @Desc    : 这是一个适用于某台服务器循环查询特定省份、特定数据上报类型的文件大小及文件个数的脚本。 
  
# 定义省份编码列表  
provinces=("110000" "120000" "130000")  
  
# 遍历省份编码列表  
for province in "${provinces[@]}"; do  
  
    # 进入省份目录  
    cd /bigdata/sftp/province/$province/1024
  
    # 执行du命令查询文件大小,并将结果输出到对应的省份编码txt文件  
    du -sh 2023-10-* >> /opt/"$province"_file_size.txt  
  
    # 执行for命令查询日期文件个数,并将结果输出到对应的省份编码txt文件  
    for date in $(ls -d */ | cut -d'/' -f1);   
        do   
            echo $date $(ls -1 $date | wc -l) >> /opt/"$province"_file_count.txt  
        done  
  
    # 返回上级目录  
    cd ..  

done

脚本 8:该脚本主要用于为某些特定的 XML 文件在特定时间段内的修改情况,并把结果保存在日志中。

bash 复制代码
#!/bin/bash  
  
# 获取当前日期  
current_date=$(date +%Y-%m-%d)  
  
# 第一条命令  
directory_path="/bigdata/sftp/province/110000/yidong/1024/$current_date"  
output_file="/opt/log_110000_yidong_$current_date.txt"  
cd "$directory_path" && ls -l *.xml | awk '{print $8,$9}' | grep -v '^$' | awk -F '[/:]' '{hour=substr($1,1,2); if ((hour >= "00" && hour < "08") || (hour >= "10" && hour < "12") || (hour >= "14" && hour <= "24")) print}' >> "$output_file" 
  
# 第二条命令  
directory_path="/bigdata/sftp/province/120000/dianxin/1024/$current_date"  
output_file="/opt/log_120000_dianxin_$current_date.txt"  
cd "$directory_path" && ls -l *.xml | awk '{print $8,$9}' | grep -v '^$' | awk -F '[/:]' '{hour=substr($1,1,2); if ((hour >= "00" && hour < "08") || (hour >= "10" && hour < "12") || (hour >= "14" && hour <= "24")) print}' >> "$output_file"  
  
# 第三条命令  
directory_path="/bigdata/sftp/province/130000/liantong/1024/$current_date"  
output_file="/opt/log_130000_liantong_$current_date.txt"  
cd "$directory_path" && ls -l *.xml | awk '{print $8,$9}' | grep -v '^$' | awk -F '[/:]' '{hour=substr($1,1,2); if ((hour >= "00" && hour < "08") || (hour >= "10" && hour < "12") || (hour >= "14" && hour <= "24")) print}' >> "$output_file"
  
# 退出进程  
exit

首先使用date命令获取当前日期,格式为:YYYY-MM-DD,并自定义current_date变量。

然后,自定义了一个目录路径directory_path和输出文件output_file

使用ls -l *.xml列出所有以.xml结尾的文件,通过awk '{print $8,$9}'提取文件的修改时间和大小信息,grep -v '^$'过滤掉空行,awk -F '[/:]' '{hour=substr($1,1,2); if ((hour >= "00" && hour < "08") || (hour >= "10" && hour < "12") || (hour >= "14" && hour <= "24")) print}'筛选出每天的00:00-07:59、10:00-11:59、14:00-23:59时间段内修改的文件,并输出它们的修改时间和大小信息,将结果追加到指定的输出文件中。

脚本 9:该脚本主要用于监控系统资源使用情况,获取并记录了磁盘使用情况、CPU空闲情况、内存空闲情况和进程总数,并将这些打印信息输出到某个日志文件中。

bash 复制代码
#!/bin/bash

date=$(date +%Y-%m-%d-%H:%M:%S)

#1、打印磁盘使用情况
DISK_1=$(df -h | awk '{printf $NF} {printf "使用率:"} {print $5} '| grep appslog | grep -v 'Filesystem')
DISK_2=$(df -h | awk '{printf $NF} {printf "使用率:"} {print $5} '| grep bigdata | grep -v 'Filesystem')
DISK_3=$(df -h / | awk '{printf $NF} {printf "使用率:"} {print $5} '| grep / | grep -v 'Filesystem')

#2、打印 CPU 空闲情况
CPU=$(top -n 1 | grep Cpu | awk 'BEGIN {printf"CPU 空闲使用率:"} {print $8}')

#3、打印内存空闲情况
MEMORY=$(free -h | awk 'BEGIN {printf"内存空闲使用率:"} NR==2 {print $4}')

#4、打印进程总数
JINCHENG=$(ps aux | wc -l | awk 'BEGIN {printf"进程总数:"} {print $1}')

echo -e "\n $date\n\n $DISK_1\n\n $DISK_3\n\n $CPU\n\n $MEMORY\n\n $JINCHENG\n" >> /opt/jacktian/inspection.log

exit

done
  • date=$(date +%Y-%m-%d-%H:%M:%S):获取当前日期和时间,格式为:年-月-日-时:分:秒
  • DISK_1、DISK_2、DISK_3:该变量用于获取磁盘的使用情况。使用df -h命令获取磁盘信息,然后使用awk提取出使用率和文件系统名称。grep用于筛选出特定名称的磁盘(如:appslog 和 bigdata)
  • CPU:该变量获取CPU的空闲使用率。使用top -n 1命令获取系统状态,然后使用grepawk提取出CPU的空闲使用率
  • MEMORY:该变量获取了内存的空闲使用率。使用free -h命令获取内存信息,然后使用awk提取出空闲内存的使用率
  • JINCHENG:该变量获取了系统的进程总数。使用ps aux命令获取进程信息,然后使用wc -l命令统计行数,即进程总数
  • echo -e "\n $date\n\n $DISK_1\n\n $DISK_3\n\n $CPU\n\n $MEMORY\n\n $JINCHENG\n":这部分将上述所有的打印信息拼接在一起,并输出到日志文件中

脚本 10:该脚本主要用于定期循环连接 FTP 服务器的访问情况,当异常时通过企业微信机器人发送告警信息。

bash 复制代码
#!/bin/bash

# FTP IP 列表
FTP_IPS=("IP_1" "IP_2" "IP_3")

#企业微信机器人地址(需要根据实际机器人地址配置)
WEBHOOK_URL=https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=XXX

#循环执行检测方法

while :
do

       date=$(date +%Y-%m-%d-%H:%M:%S)

# 循环遍历 FTP IP 列表
for ip in "${FTP_IPS[@]}"
do
  # 连接 FTP 服务器
  ftp -n $ip <<EOF

  # 退出 FTP 服务器
  exit

EOF

  # 检查上一条命令的退出状态码
  if [ $? -ne 0 ];
  	  then
  
  # 如果退出状态码不为 0,则表示命令执行失败,发送异常的告警到企业微信机器人
    curl --location --request POST ${WEBHOOK_URL} \
--header 'Content-Type: application/json' \
-d '{"msgtype": "markdown", "markdown": {"content": "'$date' FTP 访问异常:$ip"}}'
    echo "$date FTP 访问异常:$ip" >>/opt/ftp_check/ftp_check.log

    else
  # 如果退出状态码为 0,则表示命令执行成功,不发送正常的告警到企业微信机器人
    echo "$date FTP 访问正常:$ip" >>/opt/ftp_check/ftp_check.log
    fi
done
exit
done
  • FTP_IPS:该变量中包含了多个FTP服务器的IP地址
  • WEBHOOK_URL:该变量为企业微信机器人的地址,需要将 XXX 部分替换为实际的企业微信机器人的key
  • 使用了while循环来定期执行检测。在每次循环中,将获取当前日期和时间,遍历FTP_IPS列表。对于列表中的每个IP地址,脚本会尝试连接到FTP服务器
  • 如果连接命令ftp -n $ip执行失败,则退出状态码不为:0,则表示FTP访问异常。在这种情况下,脚本会发送一个异常告警到企业微信机器人,并将相关信息写入日志文件
  • 如果连接命令执行成功,退出状态码为:0,则表示FTP访问正常,脚本将不发送告警信息,只是在日志中记录正常访问的信息

以上就是今天所要分享的全部内容了。

如果你觉得这篇文章对你有点用的话,为本文点个赞留个言 或者转发一下,让更多的朋友看到,因为这将是我持续输出更多优质文章的最强动力!

相关推荐
bysking16 分钟前
【前端-组件】定义行分组的表格表单实现-bysking
前端·react.js
王哲晓32 分钟前
第三十章 章节练习商品列表组件封装
前端·javascript·vue.js
fg_41135 分钟前
无网络安装ionic和运行
前端·npm
理想不理想v37 分钟前
‌Vue 3相比Vue 2的主要改进‌?
前端·javascript·vue.js·面试
酷酷的阿云1 小时前
不用ECharts!从0到1徒手撸一个Vue3柱状图
前端·javascript·vue.js
微信:137971205871 小时前
web端手机录音
前端
齐 飞1 小时前
MongoDB笔记01-概念与安装
前端·数据库·笔记·后端·mongodb
LunarCod1 小时前
WorkFlow源码剖析——Communicator之TCPServer(中)
后端·workflow·c/c++·网络框架·源码剖析·高性能高并发
神仙别闹1 小时前
基于tensorflow和flask的本地图片库web图片搜索引擎
前端·flask·tensorflow
码农派大星。2 小时前
Spring Boot 配置文件
java·spring boot·后端