Linux随笔4-shell脚本的几个简单示例

本文介绍了如何利用Linux Shell脚本和单行命令获取系统特定信息,包括统计默认shell为/sbin/nologin的用户、找出UID最大值及其对应信息、统计远程连接IP及排序。此外,还展示了两个实用脚本,一个用于显示系统分区中利用率最高的分区,另一个显示主机系统信息,包括主机名、IPv4地址、OS版本、CPU模型、内存大小和磁盘信息。
摘要由CSDN通过智能技术生成


关于Linux的shell脚本,是由函数以及逻辑控制语句将一些命令按照特定的目的组合在一起,性能特定的功能模块集合。这个命令集合可以用于以后对相同场景的重复应用。而可重用,也是实现脚本的一个初衷吧,将重复的工作交给脚本来完成。

下面通过几个例子,慢慢复杂化这种命令集合。

1. 单行命令组合获取特定的信息

这块将会通过3个简单的示例,通过一行命令获取特定的信息。

1.1. 统计/etc/passwd文件中默认shell为/sbin/nologin的用户个数,并显示用户名

先看完整的命令以及结果:

root@ubuntu20u04:~/test# gawk -F':' '$7 ~ /sbin\/nologin/ {sum+=1; print $1 " ==> " $7} END{print "User_Count: " sum}' passwd 
daemon ==> /usr/sbin/nologin
bin ==> /usr/sbin/nologin
sys ==> /usr/sbin/nologin
games ==> /usr/sbin/nologin
man ==> /usr/sbin/nologin
lp ==> /usr/sbin/nologin
mail ==> /usr/sbin/nologin
news ==> /usr/sbin/nologin
uucp ==> /usr/sbin/nologin
proxy ==> /usr/sbin/nologin
www-data ==> /usr/sbin/nologin
backup ==> /usr/sbin/nologin
list ==> /usr/sbin/nologin
irc ==> /usr/sbin/nologin
gnats ==> /usr/sbin/nologin
nobody ==> /usr/sbin/nologin
systemd-network ==> /usr/sbin/nologin
systemd-resolve ==> /usr/sbin/nologin
systemd-timesync ==> /usr/sbin/nologin
messagebus ==> /usr/sbin/nologin
syslog ==> /usr/sbin/nologin
_apt ==> /usr/sbin/nologin
uuidd ==> /usr/sbin/nologin
tcpdump ==> /usr/sbin/nologin
landscape ==> /usr/sbin/nologin
sshd ==> /usr/sbin/nologin
systemd-coredump ==> /usr/sbin/nologin
slackware ==> /sbin/nologin
User_Count: 28
root@ubuntu20u04:~/test#

上述命令中,通过一条gawk命令,列出了默认shell为/sbin/nologin的用户并且统计了总共的用户个数。gawk命令的-F':'选项等同于默认变量FS=':',表示文件的域分隔符,默认为空白符,此处采用:号来分隔/etc/passwd文件中的各个域。

另外,通过指定第7域是否能够匹配(~)/sbin/nologin,来决定是否执行后面的对sum的自加操作,如果能够匹配,则将sum加1,每匹配到一行,则执行一次加1操作,并且将该行的用户名以及对应的默认shell打印出来。当所有行都循环迭代完成之后,此时gawk的语句体部分就会执行END部分的语句,此时打印sum值,即为搜索过所有行之后,将所有默认shell为/sbin/nologin的行相加在一起的结果。通过gawk命令的内建print命令进行打印输出。

1.2. 列出/etc/passwd文件中UID最大的值,以及对应的用户名、和默认shell

先看具体的代码以及执行结果,具体如下所示:

root@ubuntu20u04:~/test# max_uid=`gawk -F':' 'BEGIN{uid=0} {if($3 > uid) uid=$3} END{print uid}' passwd`
root@ubuntu20u04:~/test# gawk -F':' -v maxuid=$max_uid '{if($3 == maxuid) print "maxuid_name: "$1, "\nmaxuid_uid: "$3, "\nmaxuid_shell: "$7}' passwd 
maxuid_name: nobody 
maxuid_uid: 65534 
maxuid_shell: /usr/sbin/nologin
root@ubuntu20u04:~/test#

上述代码中,同样用到了gawk这个命令,以及命令替换,命令替换有两种形式:第一种为上述的反引号括起来的部分,即第一行中,等号后面的内容,为命令替换的部分;第二种为$()的这种形式,将上述反引号中的命令内容放置到上述的小口号中即可。

上述第一行获得到了/etc/passwd文件中的最大的UID的数值。第二行命令通过gawk的-v选项,将shell变量转换为gawk的变量,在gawk中引用变量内容是无需使用$符号进行引用的,所以在gawk的语句体中使用maxuid这个变量的时候,是无需加$符号进行引用的。

上述第二行代码中,gawk的语句体部分,通过搜索/etc/passwd文件中的所有行的第3域是否为max_uid中记录的最大值,如果是,则打印出用户名、用户ID以及其默认shell。

1.3. 统计当前主机中远程连接IP的连接数,并按从大到小进行排序

先看下面的具体命令以及结果,具体如下所示:

root@ubuntu20u04:~/scripts# ss -nta -4 | tr -s ' ' | cut -d' ' -f 4 | tail -n+2 | cut -d':' -f1 | sort -n | uniq -c | sort -nr -k1 | egrep -v 127\.
      2 192.168.122.30
      2 0.0.0.0
root@ubuntu20u04:~/test#

上述通过ss命令列出所有到本机的连接,通过-4选项表示仅输出IPV4格式的IP地址,通过tr -s ' '将每行的多个空格压缩为1个,随后通过cut命令提取出IP地址。

要统计各个ip地址对本机的连接次数,就需要用到uniq -c这个命令,而这个命令要想达到期望的结果,就需要对结果进行排序之后再应用该命令,所以该命令通常用在sort命令之后,通过管道,将sort的排序结果输出给uniq进行统计。

最后的egrep -v 127\.表示对搜索pattern进行取反,即不显示被127.匹配到的行。

2. 通过脚本获取特定的信息

2.1. 通过脚本显示当前系统分区中利用率最高的分区

脚本内容如下所示:

#!/bin/bash



#***********************************************************
# Name: disk.sh
# Vers: v0.1
# Auth: 六弦企鹅
# Modi: 2021-04-04
# Desc: find out the max usage of partion
# Usag: bash disk.sh
#***********************************************************

echo 'System partition usage: '
df -hT | egrep 'ext|xfs' | sort -nr -k6 | gawk '{print "Used: "$6, "Partition: "$7}'


echo -e '\n*******************************************************\n'

echo 'Max partition Usage: '
max_usage=`df -hT | egrep 'ext|xfs' | sort -nr -k6 | gawk '{print "Used: "$6, "Partition: "$7}' | head -n1`
echo -e "\e[1;42;31m$max_usage\e[0m"

上述脚本中,过滤出文件系统类型为’ext’或者’xfs’的分区,由于其他分区多为tmpfs类型的分区,是内存分区,不占用磁盘空间,所以并不做统计。而要在df命令的输出中显示文件系统类型,就需要加上额外的选项-T才可以。

随后通过排序,将结果按照利用率从高到底进行排序,这是通过sort -nr -k6这条命令实现的,选项-nr表示按照数字进行反向排序,即从大到小排序;选项-k6表示对第6域进行排序。

随后将排序结果通过管道输出给gawk命令,并打印出使用率以及挂载点。

而要打印使用率最高的分区,由于此前是按照使用率从高到低进行排序的,所以此处直接通过head -n1命令即可取出使用率最高的分区。

另外,在上述输出中,还增加了颜色,颜色控制部分的结构为"\e[1;42;31m…\e[0m",其中1表示加粗,42表示设置背景色,31表示设置字体的前景色。最后的0表示颜色应用的范围终止,该条命令之后的内容不做颜色控制。

上述脚本的执行效果如下:

root@ubuntu20u04:~/scripts# bash disk.sh
System partition usage: 
Used: 46% Partition: /boot
Used: 27% Partition: /

*******************************************************

Max partition Usage: 
Used: 46% Partition: /boot
root@ubuntu20u04:~/scripts# 

图示结果如下:
在这里插入图片描述

2.2. 通过脚本systeminfo.sh显示主机的系统信息

脚本的具体内容以及执行效果具体如下所示:

#!/bin/bash



#************************************************************
# Name: systeminfo.sh
# Vers: v0.1
# Auth: 六弦企鹅
# Modi: 2021-04-04
# Desc: output basic informations of the system
# Usag: bash systeminfo.sh
#***********************************************************


# 1. output hostname
host_name=`hostname`

# 2. ipv4 address
ipv4_address=`ip addr show enp1s0 | gawk '/inet /{print $2}' | cut -d'/' -f1`

# 3. os version
# both RHEL/CentOS and Ubuntu all have this file
os_vers=`egrep -i 'pretty_name' /usr/lib/os-release | cut -d'"' -f2`

# 4. CPU model
cpu_model=`lscpu | egrep -i 'model name' | cut -d':' -f2 | tr -s ' ' | egrep -o '[[:alpha:]].*'`

# 5. memory size
mem_size=`lsmem | egrep -i 'total online memory' | egrep -o '[[:digit:]]{1,}[G|g|T|t|M|m]{1}'`

# 6. disk info
disk_info=`df -hT | egrep 'ext|xfs' | gawk '{print "device: "$1, "\ntotal_size: "$3, "\nused_percent: "$6, "\nmount_point: "$7; print "\n"}'`

# exit the script
function exit_query(){
    echo -e 'Exiting the Query...'
    exit 0
}

PS3='Enter a number to view the information about the system(1-7): '
select info in host_name ipv4_address os_vers cpu_model mem_size disk_info exit_query
do
    case $REPLY in
        1)
            echo -e "\e[1;37mHostName: \e[0m \e[1;33m$host_name\e[0m"
            ;;
        2)
            echo -e "\e[1;37mIPADDRESS: \e[0m \e[1;33m$ipv4_address\e[0m"
            ;;
        3)
            echo -e "\e[1;37mOS_VERSION: \e[0m \e[1;33m$os_vers\e[0m"
            ;;
        4)
            echo -e "\e[1;37mCPU_MODEL: \e[0m \e[1;33m$cpu_model\e[0m"
            ;;
        5)
            echo -e "\e[1;37mMEMORY_SIZE: \e[0m \e[1;33m$mem_size\e[0m"
            ;;
        6)
            echo -e "\e[1;37mDISK_INFO: \e[0m \e[1;33m$disk_info\e[0m"
            ;;
        7)
            exit_query
            ;;
        *)
            echo -e "\e[1;31mInvalid value, PLEASE ReENTER!!!\e[0m"
            ;;
    esac
done 

上述脚本的执行效果如下所示:

root@ubuntu20u04:~/scripts# bash systeminfo.sh
1) host_name
2) ipv4_address
3) os_vers
4) cpu_model
5) mem_size
6) disk_info
7) exit_query
Enter a number to view the information about the system(1-7): 1
HostName:  ubuntu20u04
Enter a number to view the information about the system(1-7): 2
IPADDRESS:  192.168.122.30
Enter a number to view the information about the system(1-7): 3
OS_VERSION:  Ubuntu 20.04.2 LTS
Enter a number to view the information about the system(1-7): 4
CPU_MODEL:  AMD EPYC Processor (with IBPB)
Enter a number to view the information about the system(1-7): 5
MEMORY_SIZE:  2G
Enter a number to view the information about the system(1-7): 6
DISK_INFO:  device: /dev/mapper/vg0-lv--0--root 
total_size: 46G 
used_percent: 27% 
mount_point: /


device: /dev/vda2 
total_size: 469M 
used_percent: 46% 
mount_point: /boot
Enter a number to view the information about the system(1-7): 7
Exiting the Query...
root@ubuntu20u04:~/scripts#

图示结果如下图所示:
在这里插入图片描述
上述脚本中,用到了函数function,以及select语句结构和case条件选择语句结构。

  1. 对于function的定义,主要有三种形式:

    • func_name(args) {commands}
    • function func_name {commands}
    • function func_name(args) {commands}
  2. select语句结构的一些说明
    select语句结构的输出提示部分会占用系统的PS3提示符,所以此处将提示信息赋值给PS3这个系统变量,另外,select语句体中的输入值会存储在默认的环境变量REPLY中,所以后面case语句体中会对该变量进行值判断。由于select也是一种循环结构,所以在语句体部分也是以do开头,以done结尾。

  3. case语句结构的一些说明
    case语句作为条件选择语句,同if条件判断语句的语法结构类似,也是以逆序的case作为语句体的结尾。其中每个选择子句中的结尾都要以双分号结尾。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值