学shell脚本别硬啃!O‘Reilly指南带你轻松读懂代码示例

网安智编 厦门萤点网络科技 2025-12-12 00:10 56 0
linux shell脚本学习指南 更新时间:2022年09月23日 08:19:16   作者:八戒 这篇文章主要介绍了linux shell脚本学习指南的相关资料,需要的朋友可以参考下 从头一来二去阅读语法和命令说明,对于脚本小白来说比...

linux shell脚本学习指南

更新时间:2022年09月23日 08:19:16   作者:八戒

这篇文章主要介绍了linux shell脚本学习指南的相关资料,需要的朋友可以参考下

从头一来二去阅读语法和命令说明,对于脚本小白来说比较枯燥,难以坚持,所以这里选择对一份完整的shell脚本代码来逐行逐段解读,希望可以渡一渡小白,帮助我们快速进入脚本的大门。

老司机要开车了:

#!/bin/sh

用注释的形式说明文件打开类型,此处意指本脚本需要用 /bin/sh 打开。

#V1.0 Added hardware type detection
#V1.1 xxxx-xx-xx 重构脚本
#V1.2 xxxx-xx-xx 将日志信息输出到U盘
#V1.3 xxxx-xx-xx 读取存储的检测结果值
#V1.4 xxxx-xx-xx 添加校验程序版本,U盘下有对应版本信息文件才校验

上面几行表示注释内容。单行注释,以#开始

UDiskMountDir=$(df | grep /mnt/sd | awk 'END{print $NF}')

声明变量 并赋值。

$()括号内填入命令并执行,最后返回输出到变量 。

df命令显示系统上的文件系统磁盘使用情况统计。后边还可以带选项,执行更复杂的输出。命令后边加 '|' 表示将此命令的输出作为后边紧接着的命令的输入。

grep命令用于对文本按行搜索然后输出该行。英文全称 (RE) and print out the line。grep /mnt/sd 表示搜索输入信息里包含 /mnt/sd的一行,并输出该行。

awk命令用于对文本处理,END表示执行最后的运算或者打印最终的输出结果,这里用于打印输出,$NF 表示列数,print $NF 表示打印最后一个字段,各个字段默认以空格划分,可用选项 -F指定使用什么字符串来划分。

LogFile=${UDiskMountDir}/Debug.log

声明变量 并以右边的内容赋值。将变量 所代表的路径名与后边的字符串结合为新的文件名。一般命令中用到的文件名,要不是带相对路径的文件名,如 .//,就是带绝对路径的文件名,如 /root//。

${} 表示引用变量 的值。

AllCheckPassed=true

声明变量 并赋值为true。

AddError()
{
    AllCheckPassed=false
    echo "-200" > /tmp/VerCheckRes
}

声明函数 ,输入参数无需声明。

变量 赋值为true。

echo命令用于输出字符串。echo "-200" > /tmp/ 将 -200 输出到文件 /tmp/ 并覆盖原有内容。如果将符号 > 换成 >> 则是将内容追加到最后位置。

AddRecord()
{
    if [ ! -d "/userdata/recordsDir/" ];then
        mkdir -p /userdata/recordsDir/
    fi
    echo "$*" > /userdata/recordsDir/test
    sync
    AddDebugLog2UDisk $*
}

声明函数 。

if 表示 if 语句的开始。if方括号内填判断条件,如为 true 则执行 then 后的语句,否则跳出 if 语句。fi表示 if 语句的结束。和 C 语言类似,if 语句也可以有 else 甚至 else if (shell 内应该写成 elif)。if/elif 和 then 如果不在同一行则可以省略符号 ;。if

! -d "///"

判断目录 /// 是否存在,并对结果值取反(!)。

mkdir命令用于构建目录。带选项 -p表示构建路径下所有的目录。mkdir -p ///创建目录 ///, // 如果不存在也会被构建。

echo "$*" > ///test 将函数输入的所有参数都输出到文件 '///test' 并覆盖原有内容。'$*' 表示当前函数或者脚本的所有输入参数,由于在函数内引用,所以这里表示函数的所有输入参数。

sync命令用于数据同步。Linux 系统中写入硬盘的数据往往会被先存放于 中,这样是为了效率起见,但是如果系统突然断电,那么数据就会丢失,这时可以调用 sync 将 中的数据同步到硬盘。

 $* 调用函数 并传入当前函数()的所有参数。

AddDebugLog2UDisk()
{
    echo "$*" >>"$LogFile"
    sync
}

声明函数 。

echo "\$*" >>"$" 表示将函数的所有输入参数输出到变量 表示的文件中,以追加的形式输入到文件末尾。

sync同步数据到硬盘。

#生成下/tmp/App/version.txt版本信息

注释内容

rm -f "$LogFile"

oreilly:shell脚本学习指南_Linux shell脚本学习指南_shell脚本入门教程

rm命令用于移除文件。选项 -f表示强制。rm -f "$"强制移除变量 代表的文件,变量 存储的是文件名,包括路径。

echo "0" > /tmp/VerCheckRes

输出字符串 '0' 到文件 /tmp/

sh /data/bin/run_normal.sh

在当前的环境中使用另一个shell来执行脚本文件 /data/bin/.sh,当前环境中变量的值可以在新脚本(/data/bin/.sh)中被使用(非引用,如果使用 则变为引用),新脚本文件属性可以无执行权限。sh后边可以带选项 -n、-x等,-n 用于进行shell脚本的语法检查,-x用于实现shell脚本的逐句跟踪调试并打印该行命令和状态等。

sleep 2

阻塞当前进程,睡眠 2 秒,和 sleep 2s 同样效果。sleep 2h 表示睡眠 2 小时。

sh /tmp/App/kill.sh

执行脚本文件 /tmp/App/kill.sh

killall MachineCheckNode

杀掉进程 ,为进程名。

lastSNScanResult=$(cat /userdata/recordsDir/scan)

读取文件 ///scan 内容并赋值给变量 。

cat命令用于连接文件并输出内容到标准输出。

AddDebugLog2UDisk "last sn scan result:$lastSNScanResult"

调用函数,并传递字符串 last sn scan :$,$ 获取变量 的值然后和前面的字符串结合成新的字符串。

#检查SN和markData
if [ ! -f /data/bin/sysData/sn ]; then 
    AddRecord "sn missing"
    AddError
else
    snContent=$(cat /data/bin/sysData/sn)
    AddRecord "sn is:$snContent"
    snLen=$(cat /data/bin/sysData/sn | awk '{print length($0)}')
    if [ "$snLen" != "16" ] ; then
        AddRecord "sn length error $snLen"
        AddError
    fi
fi

if

! -f /data/bin//sn

判断文件 /data/bin//sn 是否是常规文件而且存在,'!' 表示对结果值取反。

如果文件 /data/bin//sn 找不到或者不是常规文件,则调用后边的语句块,直到 else 为止。调用函数 (传入字符串 "sn ") 和 (无参数传入)。

否则,获取文件内容并赋值给变量 ,调用函数 (输入 sn is:$", 字符串其中会插入变量 的值);声明变量 snLen,赋值为命令 cat /data/bin//sn | awk '{print ($0)}'的执行结果;判断 snLen 是否不等于 16,是则调用函数 和 。

$(cat /data/bin//sn | awk '{print ($0)}') 读取文件 /data/bin//sn 的内容,通过管道('|')输入到后一命令语句,awk 计算输入内容的第一字段的字符长度并输出。

if [ ! -f /data/bin/sysData/markData ]; then 
    AddRecord "markData missing"
    AddError
fi

判断文件 /data/bin// 是否不存在,不存在则调用后边的语句(以 fi 为止)。

#检验版本信息
while read -r line || [ -n "${line}" ]; do
    [ "$line" = "" ] && continue
    item_filename=$(echo "$line" | awk -F":" '{print $1}')
    item_filemd5=$(echo "$line" | awk -F":" '{print $2}')
    if [ ! -e "$item_filename" ]; then
        AddRecord "$item_filename missing"
        AddError
    fi
    acture_md5=$(md5sum "$item_filename" | awk '{print $1}')
    if [ "$item_filemd5" = "$acture_md5" ]; then
        continue
    else
        AddRecord "$item_filename" "md5 diff! file:" "$item_filemd5" "acture:" "$acture_md5"
        AddError
    fi
done 

while read xxx; do...

done