linux shell编程

本文介绍了Linuxshell编程的基础知识,包括快速入门、常用功能如图片比较、截屏、自动输入密码、文件操作和CPU负载监控。详细讲解了命令行工具如ImageMagick、grep和sed的运用。

Linux shell编程

    • 一、快速入门
    • 二、常用功能
      • 1. 常用符号
        • 1.1 `>`, `>>`, `&`, `&&`
      • 2. 比较图片差异
      • 3. 截屏
        • 3.1 起X情况下(X window起桌面)
        • 3.2 没有起X或没有X系统环境下
      • 4. 自动输入密码
      • 5. 查找根目录下以".ko"结尾的文件
      • 6. 修改文件命名
      • 7. 修改文件内容
    • 三、句子记录
      • 1. 获取CPU15min内平均负载
    • 四、项目小脚本
      • 1. 工具集成导致运行路径变化

一、快速入门

  1. 书籍:《Linux Shell 核心编程指南》丁明一
    第一章边看边跑,看完就可以直接根据需求借助GPT边做边学。
  2. 直接上手写脚本:问GPT,验证脚本可用性,并针对不足要求GPT改进脚本实现功能,看不懂的句子让GPT解释shell用法和功能。

二、常用功能

1. 常用符号

1.1 >, >>, &, &&
  1. > (重定向输出)
    用于将命令的标准输出重定向到一个文件。如果文件已存在,它将覆盖文件的内容。
  2. >> (追加输出)
    用于将命令的标准输出追加到文件的末尾。如果文件不存在,它会创建一个新文件
  3. 文件描述符 0、1、2
    0:准输入stdin
    1:标准输出stdout、
    2:标准错误输出stderr。
    常用command > output.txt 2>&1 将标准输出和标准错误输出都重定向到同一文件。
  4. & (后台执行)
    用于将命令放入后台执行。这样可以继续在命令行中执行其他命令,而不必等后台任务完成。
  5. && (条件执行)
    用于在前一个命令成功(返回状态码为0)时才执行后一个命令。它用于串联多个命令,保证前一个命令成功时才继续执行后一个命令。

2. 比较图片差异

if compare -metric AE p1.png p2.png null: 2>&1 | grep -v "0$"; then
    echo "两张图片不同"
else
    echo "两张图片相同"
fi
  • compare -metric AE p1.png p2.png null: 2>&1:这部分代码使用 ImageMagick 的 compare 命令来比较两张图片 p1.pngp2.png 的差异。其中,-metric AE 表示使用绝对误差(Absolute Error)作为度量标准。null: 是一个特殊的输出文件名,用于将结果输出到空设备,而不产生实际输出。2>&1 将错误输出重定向到标准输出,这样可以捕获错误信息。
  • | grep -v "0$":使用管道将 compare 命令的输出传递给 grep 命令进行过滤。-v 参数表示只输出不匹配模式的行,“0$” 是一个正则表达式,表示以 0 结尾的行。所以这个部分的作用是删除输出中值为 0 的行。
  • then echo "两张图片不同":如果 compare 命令的输出中存在非零的行(即两张图片不同),则输出 “两张图片不同”。
  • else echo "图片相同":如果 compare 命令的输出中不存在非零的行(即两张图片相同),则输出 “图片相同”。
  • fi:表示条件语句的结束。

至于为什么除了图片是否相同的提示外还会输出数字,这是因为 compare 命令使用 -metric AE 参数时,会计算出两张图片的差异值,并将其作为输出之一。如果两张图片完全相同,则差异值为 0。而这段代码通过 grep -v "0$" 过滤掉了差异值为 0 的行,所以只要输出中存在非零行,就会被判断为两张图片不同。

如果你不希望输出差异值,可以将代码修改为以下形式:

if compare -metric AE p1.png p2.png null: 2>&1 | grep -v "0$" > /dev/null; then
    echo "两张图片不同"
else
    echo "两张图片相同"
fi

这样,通过将 grep 命令的输出重定向到 /dev/null,就不会显示差异值了。

3. 截屏

3.1 起X情况下(X window起桌面)

可使用import截屏

import -window root screenshot.png
  • import:这是ImageMagick软件包中的一个命令,用于从屏幕或窗口中截图。

  • -window root:这是import命令的一个选项,指定要截取的窗口。在这种情况下,"root"表示截取整个屏幕。

  • screen.png:这是截图保存的文件名。你可以根据需要更改文件名或路径。

请注意,为了运行该命令,你需要系统中已经安装了ImageMagick软件包。如果你在自己的计算机上运行该命令,请确保已正确安装ImageMagick,并且在命令行环境中可用。

import 和 convert 命令隶属于 ImageMagick 软件包。你可以通过运行以下命令来安装 ImageMagick 软件包

Debian/Ubuntu:sudo apt-get install imagemagick
CentOS/RHEL:sudo yum install ImageMagick
Arch Linux:sudo pacman -S imagemagick
3.2 没有起X或没有X系统环境下

进行截屏操作可以通过 Framebuffer 来实现。使用 fbgrab 命令来对 Framebuffer 进行截屏.

sudo apt install fbcat
sudo fbgrab screenshot.png
  • 这会将 Framebuffer 的内容保存为 “screenshot.png” 文件。

命令执行后如有输出

pnmtopng: 2 colors found
  • 表示截屏结果中只包含了两种颜色。这可能是因为 Framebuffer 中的内容较为简单,只有很少的颜色变化,导致截图结果中只有两种颜色。

请注意,该方法可能需要在系统中安装额外的软件包,并且可能需要适当的权限才能执行。另外,截图的质量和效果可能会根据系统和硬件的不同而有所差异。

补充:
fbgrab 命令获取当前系统中的 Framebuffer 内容的具体过程和细节涉及一些底层操作。下面是大致的工作流程:

  1. 打开 Framebuffer 设备:
    fbgrab 首先尝试打开 Framebuffer 设备文件(通常是 /dev/fb0)。这个设备文件代表了系统中的主要 Framebuffer 设备。

  2. 获取 Framebuffer 信息:
    通过调用 ioctl 系统调用,fbgrab 会获取到关于 Framebuffer 的详细信息,包括分辨率、像素格式、每个像素的位数等。这些信息将帮助 fbgrab 确定如何解析 Framebuffer 数据。

  3. 分配内存缓冲区:
    fbgrab 根据 Framebuffer 的分辨率和像素格式,计算出需要的内存缓冲区大小,并分配足够的内存来存储 Framebuffer 的内容。

  4. 读取 Framebuffer 数据:
    通过调用 read 系统调用,fbgrab 将 Framebuffer 的内容读取到之前分配的内存缓冲区中。

  5. 转换和编码:
    一旦 Framebuffer 的内容被成功读取到内存缓冲区中,fbgrab 将根据指定的输出格式(比如 PNG)对数据进行适当的转换和编码,以生成最终的图片数据。

  6. 保存为图片文件:
    最后,fbgrab 将生成的图片数据写入一个指定的文件中,这个文件就是你在命令中指定的输出文件(比如 “screenshot.png”)。

总的来说,fbgrab 命令通过打开 Framebuffer 设备文件、读取数据、转换和编码数据,并将结果保存为图片文件的方式,获取当前系统中的 Framebuffer 内容。

需要注意的是,由于 fbgrab 涉及底层的操作,可能需要适当的权限才能执行。而且,不同系统和硬件的 Framebuffer 实现可能会有所不同,具体的细节也可能会有差异。

4. 自动输入密码

使用 read 命令和重定向来实现这个功能。具体操作如下:

  1. 在同目录下创建一个名为 password.txt 的文件,将密码写入该文件,然后保存。

  2. 在脚本中使用以下代码进行读取密码并自动输入:

#!/bin/bash

# 读取密码文件
password=$(cat password.txt)

# 执行需要密码的命令,并将密码传递给命令
echo $password | sudo -S command

其中,cat password.txt 命令用于读取 password.txt 文件中的内容,并将其赋值给变量 passwordsudo -S command 命令则是执行需要密码的命令,并通过 -S 参数将密码从标准输入中传递给命令。

这样,当需要输入密码时,脚本会自动从 password.txt 文件中读取密码,并将其传递给命令。人无需长时间观察脚本运行状态,也无需手动输入密码。

注意:为了确保密码的安全性,建议在脚本运行完毕后删除 password.txt 文件,或者将文件权限设置为仅当前用户可读写。

5. 查找根目录下以".ko"结尾的文件

在 Linux 系统中,你可以使用 find 命令来查找根目录下以 .ko 结尾的文件。以下是相应的命令示例:

find / -type f -name "*.ko"

这个命令将从根目录 / 开始,在整个文件系统中递归地查找文件名以 .ko 结尾的文件,并将它们列出。

请注意,由于这是一个递归操作,可能需要一些时间来完成。此外,由于在根目录下搜索,可能会需要管理员权限(使用 sudo)才能访问某些文件和目录。

6. 修改文件命名

你可以使用 find 命令找到当前目录下所有含有 “gc_” 或 “gc_hal_” 的文件,并使用 sed 命令来进行替换。下面是一个简单的 Shell 脚本示例,实现了这一功能:

#!/bin/bash

# 查找当前目录下所有含有"gc_"或"gc_hal_"文件名的文件,并循环处理
find . -type f -name 'gc_*' -o -name 'gc_hal_*' | while read filename; do
    # 将文件名中的"gc_"和"gc_hal_"替换为"ab_"
    newname=$(echo $filename | sed -e 's/gc_/ab_/' -e 's/gc_hal_/ab_/')
    # 执行重命名操作
    mv "$filename" "$newname"
    echo "Renamed $filename to $newname"
done

将上述代码保存到一个文件(比如 rename_files.sh),然后给予执行权限:

chmod +x rename_files.sh

接着在当前目录下执行该脚本即可:

./rename_files.sh

这个脚本会遍历当前目录以及子目录中的所有文件,将文件名中的 “gc_” 和 “gc_hal_” 替换为 “ab_”。请注意,在运行脚本之前,请务必做好必要的备份工作,以免意外情况造成文件损坏。

7. 修改文件内容

你可以使用 sed 命令来修改文件内容中的特定词汇。下面是一个简单的 Shell 脚本示例,实现了将当前目录下所有文件中的 “gc_hal_” 和 “gc_” 替换为 “ab_”:

#!/bin/bash

# 查找当前目录下的所有文件,并循环处理
find . -type f -exec sed -i 's/gc_hal_/lj_/g; s/gc_/ab_/g' {} \;

将上述代码保存到一个文件(比如 modify_files.sh),然后给予执行权限:

chmod +x modify_files.sh

接着在当前目录下执行该脚本即可:

./modify_files.sh

这个脚本会遍历当前目录以及子目录中的所有文件,将文件内容中的 “gc_hal_” 和 “gc_” 替换为 “ab_”。使用 -i 参数可以直接修改文件内容,而不需要输出到标准输出或者创建新文件。请注意,在运行脚本之前,请务必做好必要的备份工作,以免意外情况造成文件内容丢失或损坏。

三、句子记录

1. 获取CPU15min内平均负载

uptime | tr -s " " | cut -d" " -f13

这句 Shell 语句的作用是获取系统的运行时间(uptime)并提取出第 13 列。

让我们逐步解析这个命令的各个部分:

  1. uptime:这是一个 Linux 内置命令,用于显示系统的运行时间和平均负载。它会输出一行文本,类似于 “06:30:53 up 10 days, 4:23, 2 users, load average: 0.25, 0.32, 0.45”。

  2. |:这是管道符号,用于将一个命令的输出传递给下一个命令作为输入。

  3. tr -s " ":这是一个使用 tr 命令的操作,意思是将连续的多个空格字符替换为一个空格字符。-s 选项表示压缩连续的重复字符。

  4. cut -d" " -f13:这是使用 cut 命令的操作,通过指定分隔符和字段来提取特定列的内容。

    • -d" ":指定分隔符为空格。这样,cut 命令将使用空格作为字段的分隔符。
    • -f13:指定要提取的字段为第 13 列。cut 命令将根据指定的分隔符将输入的每行按列分割,并提取第 13 列的内容。

综上所述,这句 Shell 脚本的作用是从 uptime 命令的输出中提取出系统的运行时间,并输出为第 13 列的内容。

这个命令展示了一些常见的 Shell 编程技巧和用法:

  • 使用管道符号 | 将多个命令连接在一起,实现数据的流式处理。
  • 使用 tr 命令进行文本字符替换或删除操作,这里是将连续的多个空格字符替换为一个空格字符。
  • 使用 cut 命令提取指定的列或字段,通过指定分隔符和字段来进行分割和提取操作。

这些技巧可以帮助您在 Shell 脚本中处理和转换文本数据。

四、项目小脚本

1. 工具集成导致运行路径变化

背景:
有一个测试程序2DTestTool,运行的命令为./go.sh生成可执行文件2DTestTool,然后运行./2DTestTool test,是可以正常运行的。现在需要将该工具集成,放在case目录下,case下除2DTestTool还有其它测试工具,如3DTestTool等,运行命令同一改为./case/2DMassTestTool test。但是这样会引起2DTestTool传下去的运行路径不一样,导致程序中涉及相对路径的文件读取都出现问题,现在需要给出脚本将该问题解决,不采用改变工具中相对路径内容的方式。
解决:
在 case 目录下运行脚本时,设置环境变量或修改当前目录。

#!/bin/bash

# 获取当前脚本所在的目录
SCRIPT_DIR=$(cd $(dirname "$0") && pwd)

# 进入 2DMassTestTool 所在目录
cd $SCRIPT_DIR/2DTestTool

# 确保运行测试工具时的路径正确
./2DTestTool prepare

脚本详细解释:

# 获取当前脚本所在的目录
SCRIPT_DIR=$(cd $(dirname "$0") && pwd)
  • $(dirname "$0"):

    • 这部分代码获取当前脚本的路径。
    • "$0" 表示脚本文件的路径和名称。当我们运行脚本时,$0 会包含脚本的路径(相对或绝对路径)。
    • dirname "$0" 会从这个路径中提取目录部分,即去掉脚本名称,只保留脚本所在的目录路径。
    • 举个例子,如果脚本的路径是 /home/user/script/go.sh,那么 dirname "$0" 就会返回 /home/user/script
  • cd $(dirname "$0"):

    • 这部分命令进入到脚本所在的目录。cd 命令用于改变当前工作目录。
    • $(dirname "$0")cd 命令进入到脚本所在的目录。
  • pwd:

    • pwd(print working directory)命令会输出当前工作目录的绝对路径。
    • 在这个上下文中,它返回的是脚本所在目录的绝对路径,并将结果赋值给变量 SCRIPT_DIR
  • SCRIPT_DIR=$(cd $(dirname "$0") && pwd):

    • pwd 命令的输出(脚本的绝对路径)赋值给变量 SCRIPT_DIR
    • SCRIPT_DIR 现在包含脚本文件所在目录的绝对路径,例如 /home/user/script

变量解释:

  • SCRIPT_DIR:保存当前脚本所在目录的绝对路径。
  • $0:脚本文件的名称或路径(相对或绝对路径),在这里用于获取脚本所在的目录。
  • $SCRIPT_DIR/2DTestTool:指向 2DTestTool 目录的绝对路径,确保脚本能够找到并进入该目录。

通过这种方式,脚本能够在任意位置执行,并确保始终能够找到并正确运行 2DTestTool 工具,无论它在何处运行。

shell是一种完整的编程语言,易学易用;shell脚本可以使烦人的手工作业自动化,使你的工作变得简单、轻松!本书通过各种实用的系统管理小技巧和趣味脚本代码,详尽地介绍了shell编程各个不同的方面。学完本书后,你将成为一名shell编程高手。 内容简介 本书共分五部分 ,详细介绍了SHELL编程技巧,各种UNIX命令及语法,还涉及了UNIX的文字处理以及少量的系统管理问题。本书内容全面,文字简洁流畅,适合SHELL编程人员学习、参考。 目录 第一部分 SHELL 第一章 文件安全与权限 第二章 使用FIND和XARGS 第三章 后台执行命令 第四章 文件名置换 第五章 SHELL输入输出 第六章 命令执行顺序 第二部分 文本过滤 第七章 正则表达式介绍 第八章 GERP家族 第九章 AWK介绍 第十章 SED用法介绍 第十一章 合并与分割 第十二章 TR用法 第三部分 登录环境 第十三章 登录环境 第十四章 环境和SHELL变量 第十五章 小结 第四部分 基础SHELL编程 第十六章 SHELL脚本介绍 第十七章 条件测试 第十八章 控制流结构 第十九章 SHELL函数 第二十章 向脚本传递参数 第二一章 创建屏幕输出 第二二章 创建屏幕输入 第二三章 调试脚本 第二四章 SHELL嵌入命令 第五部分 高级SHELL编程技巧 第二五章 深入讨论 << 第二六章 SHELL工具 第二七章 几个脚本例子 第二八章 运行级别脚本 第二九章 CGI脚本
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值