Linux尖刀——shell

目录

知识点

lsblk

grep

awk

tail

du

df

对新增存储设备的检测与分区

用lsblk查询块设备

用dmesg看内核打印信息 

用ls查看新增设备 

对rootfs空间使用情况的监控


知识点

首先想要用shell脚本解决一些问题肯定要熟悉linux的命令

lsblk

  • -t或–tree:以树形结构展示设备的层次关系。
  • -m或–list:显示挂载点的信息。
  • -o或–output:指定要显示的列和顺序,例如-o NAME,SIZE,TYPE只显示名称、大小和类型。
  • -a或–all:显示所有设备,包括空设备。
  • -p或–paths:显示设备的完整路径。

grep

要用好grep这个工具,其实就是要写好正则表达式,所以这里不对grep的所有功能进行实例讲解,只列几个例子,讲解一个正则表达式的写法。

1

$ ls -l | grep '^a'

通过管道过滤ls -l输出的内容,只显示以a开头的行。

1

$ grep 'test' d*

显示所有以d开头的文件中包含test的行。

1

$ grep 'test' aa bb cc

显示在aa,bb,cc文件中匹配test的行。

1

$ grep '[a-z]\{5\}' aa

显示所有包含每个字符串有5个连续小写字符的字符串的行。

1

$ grep 'w\(es\)t.*\1' aa

如果west被匹配,则es就被存储到内存中,并标记为1,然后搜索任意个字符(.*),这些字符后面紧跟着另外一个es(\1),找到就显示该行。如果用egrep或grep -E,就不用"\"号进行转义,直接写成'w(es)t.*\1'就可以了。

  • -a 或 --text : 不要忽略二进制的数据。
  • -A<显示行数> 或 --after-context=<显示行数> : 除了显示符合范本样式的那一列之外,并显示该行之后的内容。
  • -b 或 --byte-offset : 在显示符合样式的那一行之前,标示出该行第一个字符的编号。
  • -B<显示行数> 或 --before-context=<显示行数> : 除了显示符合样式的那一行之外,并显示该行之前的内容。
  • -c 或 --count : 计算符合样式的列数。
  • -C<显示行数> 或 --context=<显示行数>或-<显示行数> : 除了显示符合样式的那一行之外,并显示该行之前后的内容。
  • -d <动作> 或 --directories=<动作> : 当指定要查找的是目录而非文件时,必须使用这项参数,否则grep指令将回报信息并停止动作。
  • -e<范本样式> 或 --regexp=<范本样式> : 指定字符串做为查找文件内容的样式。
  • -E 或 --extended-regexp : 将样式为延伸的正则表达式来使用。
  • -f<规则文件> 或 --file=<规则文件> : 指定规则文件,其内容含有一个或多个规则样式,让grep查找符合规则条件的文件内容,格式为每行一个规则样式。
  • -F 或 --fixed-regexp : 将样式视为固定字符串的列表。
  • -G 或 --basic-regexp : 将样式视为普通的表示法来使用。
  • -h 或 --no-filename : 在显示符合样式的那一行之前,不标示该行所属的文件名称。
  • -H 或 --with-filename : 在显示符合样式的那一行之前,表示该行所属的文件名称。
  • -i 或 --ignore-case : 忽略字符大小写的差别。
  • -l 或 --file-with-matches : 列出文件内容符合指定的样式的文件名称。
  • -L 或 --files-without-match : 列出文件内容不符合指定的样式的文件名称。
  • -n 或 --line-number : 在显示符合样式的那一行之前,标示出该行的列数编号。
  • -o 或 --only-matching : 只显示匹配PATTERN 部分。
  • -q 或 --quiet或--silent : 不显示任何信息。
  • -r 或 --recursive : 此参数的效果和指定"-d recurse"参数相同。
  • -s 或 --no-messages : 不显示错误信息。
  • -v 或 --invert-match : 显示不包含匹配文本的所有行。
  • -V 或 --version : 显示版本信息。
  • -w 或 --word-regexp : 只显示全字符合的列。
  • -x --line-regexp : 只显示全列符合的列。
  • -y : 此参数的效果和指定"-i"参数相同。

awk

  • -F fs or --field-separator fs
    指定输入文件折分隔符,fs是一个字符串或者是一个正则表达式,如-F:。
  • -v var=value or --asign var=value
    赋值一个用户定义变量。
  • -f scripfile or --file scriptfile
    从脚本文件中读取awk命令。
  • -mf nnn and -mr nnn
    对nnn值设置内在限制,-mf选项限制分配给nnn的最大块数目;-mr选项限制记录的最大数目。这两个功能是Bell实验室版awk的扩展功能,在标准awk中不适用。
  • -W compact or --compat, -W traditional or --traditional
    在兼容模式下运行awk。所以gawk的行为和标准的awk完全一样,所有的awk扩展都被忽略。
  • -W copyleft or --copyleft, -W copyright or --copyright
    打印简短的版权信息。
  • -W help or --help, -W usage or --usage
    打印全部awk选项和每个选项的简短说明。
  • -W lint or --lint
    打印不能向传统unix平台移植的结构的警告。
  • -W lint-old or --lint-old
    打印关于不能向传统unix平台移植的结构的警告。
  • -W posix
    打开兼容模式。但有以下限制,不识别:/x、函数关键字、func、换码序列以及当fs是一个空格时,将新行作为一个域分隔符;操作符**和**=不能代替^和^=;fflush无效。
  • -W re-interval or --re-inerval
    允许间隔正则表达式的使用,参考(grep中的Posix字符类),如括号表达式[[:alpha:]]。
  • -W source program-text or --source program-text
    使用program-text作为源代码,可与-f命令混用。
  • -W version or --version
    打印bug报告信息的版本。

tail

  • -f 循环读取
  • -q 不显示处理信息
  • -v 显示详细的处理信息
  • -c<数目> 显示的字节数
  • -n<行数> 显示文件的尾部 n 行内容
  • --pid=PID 与-f合用,表示在进程ID,PID死掉之后结束
  • -q, --quiet, --silent 从不输出给出文件名的首部
  • -s, --sleep-interval=S 与-f合用,表示在每次反复的间隔休眠S秒

du

  • -a或-all 显示目录中个别文件的大小。
  • -b或-bytes 显示目录或文件大小时,以byte为单位。
  • -c或--total 除了显示个别目录或文件的大小外,同时也显示所有目录或文件的总和。
  • -D或--dereference-args 显示指定符号连接的源文件大小。
  • -h或--human-readable 以K,M,G为单位,提高信息的可读性。
  • -H或--si 与-h参数相同,但是K,M,G是以1000为换算单位。
  • -k或--kilobytes 以1024 bytes为单位。
  • -l或--count-links 重复计算硬件连接的文件。
  • -L<符号连接>或--dereference<符号连接> 显示选项中所指定符号连接的源文件大小。
  • -m或--megabytes 以1MB为单位。
  • -s或--summarize 仅显示总计。
  • -S或--separate-dirs 显示个别目录的大小时,并不含其子目录的大小。
  • -x或--one-file-xystem 以一开始处理时的文件系统为准,若遇上其它不同的文件系统目录则略过。
  • -X<文件>或--exclude-from=<文件> 在<文件>指定目录或文件。
  • --exclude=<目录或文件> 略过指定的目录或文件。
  • --max-depth=<目录层数> 超过指定层数的目录后,予以忽略。
  • --help 显示帮助。
  • --version 显示版本信息。

df

  • 文件-a, --all 包含所有的具有 0 Blocks 的文件系统
  • 文件--block-size={SIZE} 使用 {SIZE} 大小的 Blocks
  • 文件-h, --human-readable 使用人类可读的格式(预设值是不加这个选项的...)
  • 文件-H, --si 很像 -h, 但是用 1000 为单位而不是用 1024
  • 文件-i, --inodes 列出 inode 资讯,不列出已使用 block
  • 文件-k, --kilobytes 就像是 --block-size=1024
  • 文件-l, --local 限制列出的文件结构
  • 文件-m, --megabytes 就像 --block-size=1048576
  • 文件--no-sync 取得资讯前不 sync (预设值)
  • 文件-P, --portability 使用 POSIX 输出格式
  • 文件--sync 在取得资讯前 sync
  • 文件-t, --type=TYPE 限制列出文件系统的 TYPE
  • 文件-T, --print-type 显示文件系统的形式
  • 文件-x, --exclude-type=TYPE 限制列出文件系统不要显示 TYPE
  • 文件-v (忽略)
  • 文件--help 显示这个帮手并且离开
  • 文件--version 输出版本资讯并且离开

Linux尖刀——shell_第1张图片

 

对新增存储设备的检测与分区

检查新增块设备我想到了三个命令

用lsblk查询块设备

lsblk -o name,type,mountpoint | grep -i "disk" | grep -v "nvme" | grep -v "lvm" | awk     '{print $1}' | tail -n 1

lsblk的输出

Linux尖刀——shell_第2张图片

 

NAME:就是装置的文件名啰!会省略 /dev 等前导目录!
MAJ:MIN:其实核心认识的装置都是透过这两个代码来熟悉的!分别是主要:次要装置代码!
RM:是否为可卸除装置 (removable device),如光盘、USB 磁盘等
SIZE:当然就是容量啰!
RO:是否为只读装置的意思
TYPE:是磁盘 (disk)、分区槽 (partition) 还是只读存储器 (rom) 等输出
MOUTPOINT:就是前一章谈到的挂载点
我们查找了这三列元素并输出第一列的最后一个

用dmesg看内核打印信息 

dmesg | grep -ioE "sd[a-z]+|mmcblk[0-9]+" | tail -n 1

忽略大小写以正则表达式的样式来查找内核打印信息中sd开头和mmcblk开头的设备并取最后一个

服务器上新插入的块设备是sd开头的除非是自带驱动的设备,而单板上开发插入块设备是mmcblk开头的

 

用ls查看新增设备 

ls -lf /dev/sd* /dev/mmcblk* 2>/dev/null | awk -F '[/ ]' '{devices[NR]=$NF} END {print devices[NR-4]}'

        ls我没介绍这个太简单了经常用相信没人不会因为ls会连带分区一起显示出来,我当时的设备正好四个分区就显示倒数第五个数了,这个命令最不靠谱,dmesg那个也容易显示错误,因为可能有哪个程序使用了分区有时候也会在dmesg中打印出来就是可能会查错。第一个lsblk其实也不完善,因为插入的设备如果是第二次插入那检查到的就不是这个设备了,因为这个排序不少按照时间来的,是按照设备号,比如有sda  sdb 两个设备,拔掉sda在插入这个命令找到的还是sdb

        希望以后可以完善一下,暂时是为了单板启动初始化存储设备用的不存在二次插拔现象。

#检查平台
check_platform()
{
    if [ `uname -r` == "4.19.0" ]; then
        echo "The platform is ARM"
        #由于arm平台设备分区名称自动以p1~pn为自增后缀,故此进行重命名
        partition_name=$dev_name"p"
        #是否为arm平台
        platform=1
    else
        echo "The platform is X86"
        partition_name=$dev_name
        #平台为x86
        platform=0
    fi
}

又写了个检测平台是ARM还是x86的函数

对rootfs空间使用情况的监控

#!/bin/bash

# 存储初始rootfs的内容
INITIAL_CONTENTS="initial_contents.txt"

# 存储当前rootfs的内容
CURRENT_CONTENTS="current_contents.txt"

# 存储初始磁盘使用情况
INITIAL_DISK_USAGE="initial_disk_usage.txt"

# 存储当前磁盘使用情况
CURRENT_DISK_USAGE="current_disk_usage.txt"

# 检查初始rootfs内容文件是否存在
if [[ ! -f $INITIAL_CONTENTS ]]; then
    # 如果不存在,创建并保存初始rootfs的内容
    du -h -d 1 / > $INITIAL_CONTENTS
    df -h / | tail -n 1 > $INITIAL_DISK_USAGE
    echo "保存初始rootfs内容和磁盘使用情况"
else
    # 如果存在,将当前rootfs的内容与初始内容进行对比
    du -h -d 1 / > $CURRENT_CONTENTS
    df -h / | tail -n 1 > $CURRENT_DISK_USAGE
    echo "与初始rootfs内容进行对比"

    # 提取初始磁盘使用率和当前磁盘使用率
    initial_usage=$(awk '{print $5}' $INITIAL_DISK_USAGE)
    current_usage=$(awk '{print $5}' $CURRENT_DISK_USAGE)

    # 提取初始rootfs总空间、剩余空间和当前rootfs剩余空间
    total_space=$(awk '{print $2}' $INITIAL_DISK_USAGE)
    initial_free_space=$(awk '{print $4}' $INITIAL_DISK_USAGE)
    current_free_space=$(awk '{print $4}' $CURRENT_DISK_USAGE)

    # 生成初始内容文件、当前内容文件和它们之间的差异表格
    printf "%-11s | %-7s | %-6s | %-5s  |\n" "文件/目录名称" "初始大小" "当前大小" "变化量"
    printf "*****************************************\n"
    paste <(cut -f 2 $INITIAL_CONTENTS) <(cut -f 1 $INITIAL_CONTENTS) <(cut -f 1 $CURRENT_CONTENTS) <(paste <(cut -f 1 $INITIAL_CONTENTS) <(cut -f 1 $CURRENT_CONTENTS) | awk '{printf "%.2f\n", ($2-$1)}') | while IFS=$'\t' read -r file initial_size current_size change initial_free current_free initial_usage current_usage; do
        printf "%-11s | %-7s | %-6s | %-5sM |\n" "$file" "$initial_size" "$current_size" "$change"
    done
    printf "*****************************************\n"
    echo "总空间        $total_space"
    echo "初始剩余空间   $initial_free_space"
    echo "当前剩余空间   $current_free_space"
    echo "初始使用率     $initial_usage"
    echo "当前使用率     $current_usage"
fi

# 每次执行后,删除临时文件
rm $CURRENT_CONTENTS $CURRENT_DISK_USAGE

这里主要就是du和df查看然后paste和printf进行打印了比较简单

你可能感兴趣的:(脚本开发,Linux,shell,块设备,rootfs)