Linux命令行与shell脚本编程大全-3-4

第三部分高级shell脚本编程


第17章创建函数

17.1 脚本函数基础

17.1.1 创建函数

在bash shell 脚本中创建函数的语法有两种。第一种语法是使用关键字function,随后跟
上分配给该代码块的函数名:
function name {
commands
}

17.1.2 使用函数

要在脚本中使用函数,只需像其他shell 命令一样写出函数名即可

17.2 函数返回值

17.2.1 默认的退出状态码

在默认情况下,函数的退出状态码是函数中最后一个命令返回的退出状态码。函数执行结束
后,可以使用标准变量$?来确定函数的退出状态码。该函数的退出状态码是1,因为函数中的最后一个命令执行失败了。但你无法知道该函数中的其他命令是否执行成功。

17.2.2 使用return命令

使用return 命令以特定的退出状态码退出函数。return 命令允许指定一个整数值作为函数的退出状态码。当用这种方法从函数中返回值时,一定要小心。为了避免出问题,牢记以下两个技巧: 函数执行一结束就立刻读取返回值;退出状态码必须介于0~255

$ cat test5
#!/bin/bash
# using the return command in a function
function dbl {
read -p "Enter a value: " value
echo "doubling the value"
return $[ $value * 2 ]
}
dbl
echo "The new value is $?"    #用$?变量显示出该结果
$ 

17.2.3 使用函数输出

将dbl函数的输出保存到shell 变量中:result=$(dbl)

$ cat test5b
#!/bin/bash
# using the echo to return a value
function dbl {
read -p "Enter a value: " value
echo $[ $value * 2 ]
}
result=$(dbl)
echo "The new value is $result"
$

17.3 在函数中使用变量

17.3.1 向函数传递参数

函数可以使用标准的位置变量来表示在命令行中传给函数的任何参数。例如,函数名保存在
$0 变量中,函数参数依次保存在$1、$2 等变量中。也可以用特殊变量$#来确定传给函数的参数
数量。

在脚本中调用函数时,必须将参数和函数名放在同一行

17.3.2 在函数中处理变量
1. 全局变量

全局变量是在shell 脚本内任何地方都有效的变量。

在默认情况下,在脚本中定义的任何变量都是全局变量。在函数外定义的变量可在函数内正
常访问

2. 局部变量

无须在函数中使用全局变量,任何在函数内部使用的变量都可以被声明为局部变量。为此,
只需在变量声明之前加上local 关键字即可

$ cat test9
#!/bin/bash
# demonstrating the local keyword
function func1 {
local temp=$[ $value + 5 ]
result=$[ $temp * 2 ]
}

17.4 数组变量和函数

将数组变量作为函数参数进行传递,则函数只会提取数组变量的第一个元素,,必须先将数组变量拆解成多个数组元素,然后将这些数组元素作为函数参数传递。最后在函数内部,将所有的参数重新组合成一个新的数组变量。

17.4.1 向函数传递数组
$ cat test10
#!/bin/bash
# array variable to function test
function testit {
local newarray   # 创建数组
newarray=(`echo "$@"`) #所有的参数重新组合成一个新的数组变量
echo "The new array value is: ${newarray[*]}"
}
myarray=(1 2 3 4 5)
echo "The original array is ${myarray[*]}"
testit ${myarray[*]}
$
$ ./test10
The original array is 1 2 3 4 5
The new array value is: 1 2 3 4 5
$
17.4.2 从函数返回数组

函数先用echo 语句按正确顺序输出数组的各个元素,然后脚本再将数组元素重组成一个新的数组变量

$ cat test12
#!/bin/bash
# returning an array value
function arraydblr {
local origarray
local newarray
local elements
local i
origarray=($(echo "$@"))
newarray=($(echo "$@"))
elements=$[ $# - 1 ]
for (( i = 0; i <= $elements; i++ ))
{
newarray[$i]=$[ ${origarray[$i]} * 2 ]
}
echo ${newarray[*]}
}
myarray=(1 2 3 4 5)
echo "The original array is: ${myarray[*]}" 
arg1=$(echo ${myarray[*]})   # echo 语句重组成一个新的数组变量
result=($(arraydblr $arg1)) # 通过$arg1 变量将数组元素作为参数传给arraydblr 函数。
echo "The new array is: ${result[*]}" 
$
$ ./test12
The original array is: 1 2 3 4 5
The new array is: 2 4 6 8 10

17.5 函数递归

局部函数变量的一个特性是自成体系(self-containment)。除了获取函数参数,自成体系的
函数不需要使用任何外部资源。这个特性使得函数可以递归地调用,也就是说函数可以调用自己来得到结果。

17.6 创建库

bash shell 允许创建函数库文件,然后在多个脚本中引用此库文件。

在多个脚本中使用同一段代码

第一步是创建一个包含脚本中所需函数的公用库文件,例如:库文件myfuncs

第二步是在需要用到这些函数的脚本文件中包含myfuncs 库文件,用source 命令在脚本中运行库文

$ cat test14
#!/bin/bash
# using functions defined in a library file
. ./myfuncs   #  . ./  使用这个来调用
value1=10
value2=5
result1=$(addem $value1 $value2)
result2=$(multem $value1 $value2)
result3=$(divem $value1 $value2)
echo "The result of adding them is: $result1"
echo "The result of multiplying them is: $result2"
echo "The result of dividing them is: $result3"
$
$ ./test14
The result of adding them is: 15
The result of multiplying them is: 50
The result of dividing them is: 2
$

source 命令有个别名,称作点号操作符。

17.7 在命令行中使用函数

17.7.1 在命令行中创建函数
1. 采用单行方式来定义函数
$ function divem { echo $[ $1 / $2 ]; }
$ divem 100 5
 2.采用多行方式来定义函数

使用这种方法,无须在每条命令的末尾放置分号,只需按下回车键即可

$ function multem {
> echo $[ $1 * $2 ]
> }
$ multem 2 5
10
17.7.2 在.bashrc文件中定义函数
1. 直接定义函数


可以直接在用户主目录的.bashrc 文件中定义函数,只需将函数放在文件末尾即可

2. 源引函数文件


只要是在shell 脚本中,就可以用source 命令(或者其别名,即点号操作符)将库文件中
的函数添加到.bashrc 脚本中

$ cat .bashrc
# .bashrc
# Source global definitions
if [ -r /etc/bashrc ]; then
. /etc/bashrc
fi
. /home/rich/libraries/myfuncs  # 将库文件中的函数添加到.bashrc 脚本
$


第18章 图形化桌面环境中的脚本编程 #


第19章 初识sed和gawk

19.1文本处理

19.1.1 sed编辑器

sed 编辑器被称作流编辑器(stream editor)

sed 命令的格式如下: 
sed options script file

1. 在命令行中定义编辑器命令

在默认情况下,sed 编辑器会将指定的命令应用于STDIN 输入流中。因此,可以直接将数据
通过管道传入sed 编辑器进行处理。

$ echo "This is a test" | sed 's/test/big test/'
This is a big test
$#接将数据通过管道传入sed 编辑器进行处理, 替换(s)命令,将big test 替换了test
2. 在命令行中使用多个编辑器命令

如果要在sed 命令行中执行多个命令,可以使用-e 选项

$ sed -e 's/brown/red/; s/dog/cat/' data1.txt
The quick red fox jumps over the lazy cat.
The quick red fox jumps over the lazy cat.
The quick red fox jumps over the lazy cat.
The quick red fox jumps over the lazy cat.
$
3. 从文件中读取编辑器命令
 

有大量要执行的sed 命令,那么将其放进单独的文件通常会更方便一些。可以在sed
命令中用-f 选项来指定文件:

$ cat script1.sed
s/brown/green/
s/fox/toad/
s/dog/cat/
$
$ sed -f script1.sed data1.txt
The quick green toad jumps over the lazy cat.
The quick green toad jumps over the lazy cat.
The quick green toad jumps over the lazy cat.
The quick green toad jumps over the lazy cat.
$
19.1.2 gawk编辑器

虽然sed 编辑器非常方便,可以即时修改文本文件

19.2 sed编辑器基础命令 #

19.2.1 更多的替换选项 #
19.2.2 使用地址 #
19.2.3 删除行 #
19.2.4 插入和附加文本  #
19.2.5 修改行 #
19.2.6 转换命令 #
19.2.7 再探打印 #
19.2.8 使用sed处理文件 #


第20章 正则表达式

正则表达式是一种可供Linux 工具过滤文本的自定义模板


第21章 sed进阶 #


第22章 gawk进阶 # 


第23章 使用其他shell

  • dash shell
  • zsh shell

 第四部分 创建和管理实用的脚本

第24章 编写简单的脚本实用工具
第25章 井井有条

第24章 编写简单的脚本实用工具


24.1 备份

定时进行备份(也称作归档)

24.1.1 日常备份 #
24.1.2 创建按小时归档的脚本 #


24.2 删除账户

管理本地用户账户绝不仅仅是添加、修改和删除,还需考虑安全问题、保留工作的需求,以
及精确删除账户。

删除本地账户属于更复杂的账户管理任务,至少需要4 个步骤。
(1) 获取正确的待删除用户账户名。
(2)“杀死”系统中正在运行的属于该账户的进程。
(3) 确认系统中属于该账户的所有文件。
(4) 删除该用户账户。


24.3 系统监控


24.3.1 获得默认的shell审计功能

使用cut 命令获取/etc/passwd 文件中所有账户的默认shell。

$ cut -d: -f7 /etc/passwd

24.3.2 权限审计功能

SUID(set user ID)和SGID(set group ID)是两种很方便的权限设置

找出具有这两种权限的文件和目录,需要使用find 命令

$ sudo find / -perm /6000 2>/dev/null


第25章 井井有条

25.1 理解版本控制


25.1.1 工作目录

工作目录是所有脚本的创建、修改和审查之地。它通常是脚本编写者的主目录中的某个子目录,类似于/home/christine/scripts。最好为每个项目都创建一个新的子目录,因为Git 会在其中放
置文件,以便进行跟踪。

25.1.2 暂存区

暂存区也称为索引。该区域和工作目录位于同一系统。bash 脚本通过Git 命令(git add)
在暂存区内注册。通过git init 命令,暂存区在工作目录中设置了一个名为.git 的隐藏子目录。

25.1.3 本地仓库

本地仓库包括每个脚本文件的历史记录。它也会用到工作目录的.git 子目录。脚本文件的各
个版本(称为项目树)和提交信息之间的关系通过Git 命令(git commit),以对象的方式存储
在.git/objects/目录中。
项目树和提交数据合起来称为快照。每次提交数据都会创建一个新快照。不过,旧快照并不
会被删除,依然可以查看。如果需要,还可以返回到之前的快照,这是Git 另一个不错的特性。

25.1.4 远程仓库

在Git 配置中,远程仓库通常位于云端,提供代码托管服务。著名的远程仓库有GitHub、GitLab、BitBucket 和Launchpad。不过到目前为止,GitHub 最受欢迎

25.1.5 分支

Git 还提供了一个名为分支的特性,该特性可以在各种脚本项目中发挥作用。分支是本地仓
库中属于特定项目的一个区域。

25.1.6 克隆

Git 的另一个特性是复制项目。这个过程称为克隆。

注意 在Git 中,克隆(cloning)分叉(forking)是两种紧密相关的操作。使用git clone
命令将文件从远程仓库下载到本地系统,这一过程是克隆。将文件从一个远程仓库复制
到另一个远程仓库,这一过程是分叉。


25.1.7 使用Git作为VCS

好处

性能:Git只操作本地文件, 这提高了其部署速度。同远程仓库之间收发文件属于例外
情况。
历史文件:从文件被注册那一刻起, Git就开始使用索引来记录文件的内容。当对本地存
储库的提交完成时, Git会及时创建并存储对该快照的引用。
准确性:Git使用校验和来保护文件完整性。
去中心化:脚本编写者可以在同一个项目中工作,但不必位于同一网络或系统。


25.2 设置Git环境

安装好git 软件包之后,为新的脚本项目设置Git 环境涉及以下4 个基本步骤。
(1) 创建工作目录: 

$ mkdir MWGuard$ cd MWGuard/


(2) 初始化.git/子目录

$ git init
$ git remote add origin https://github.com/C-Bresnahan/MWGuard.git
$
$ git remote -v
origin https://github.com/C-Bresnahan/MWGuard.git (fetch)
origin https://github.com/C-Bresnahan/MWGuard.git (push)
$


(3) 设置本地仓库选项

#,则需将姓名和email 地址添加到Git 的全局仓库配置文件中
$ git config --global user.name "Christine Bresnahan"
$ git config --global user.email "cbresn1723@gmail.com"


(4) 确定远程仓库位置

建立好项目的远程仓库之后,需要把仓库地址记下来。随后向远程仓库发送项目文件时,要
用到这个地址。

可以使用git remote add origin URL 命令来添加地址,其中URL 就是远程仓库地址:

$ git remote add origin https://github.com/C-Bresnahan/MWGuard.git
$
$ git remote -v
origin https://github.com/C-Bresnahan/MWGuard.git (fetch)
origin https://github.com/C-Bresnahan/MWGuard.git (push)
$


25.3 使用Git提交文件

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/710613.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Multi-Head Attention详解

文中大部分内容以及图片来自&#xff1a;https://medium.com/hunter-j-phillips/multi-head-attention-7924371d477a 当使用 multi-head attention 时&#xff0c;通常d_key d_value &#xff08;d_model / n_heads&#xff09;&#xff0c;其中n_heads是头的数量。研究人员称…

01-Vue2 介绍与指令的使用

1. Vue核心 1.1. Vue简介 1.1.1. 官网 中文官网Vue.js - 渐进式 JavaScript 框架 | Vue.js (vuejs.org)https://cn.vuejs.org/ 英文官网Vue.js - The Progressive JavaScript Framework | Vue.js (vuejs.org)https://vuejs.org/ 1.1.2. 介绍与描述 VUE是构建于用户界面的渐进…

靶机渗透之sar

Name: Sar: 1Date release: 15 Feb 2020Author: LoveSeries: Sar Download: https://drive.google.com/open?id1AFAmM21AwiAEiVFUA0cSr_GeAYaxd3lQ 对于vulnhub中的靶机&#xff0c;我们都需先下载镜像&#xff0c;然后导入VM&#xff0c;并将网络连接改为NAT模式。首先我们…

UDP数据报套接字编程入门

目录 1.TCP和UDP的特点及区别 1.1TCP的特点 1.2UDP的特点 1.3区别 2.UDP Socket的api的介绍 2.1DatagramSocket API 2.2DatagramPacket API 3.回显客户端与服务器 3.1回显服务器 3.1.1UdpEchoServer类的创建 3.1.2服务器的运行方法start() 3.1.3main部分 3.1.4.完整…

C# CAD PaletteSet.Style各种外观和行为样式

ps.Style 是 Autodesk.AutoCAD.Windows.PaletteSet 类的一个属性&#xff0c;用于定义调色板集&#xff08;PaletteSet&#xff09;的各种外观和行为样式。它可以是 PaletteSetStyles 枚举类型的组合值 PaletteSetStyles 枚举中包含以下一些选项&#xff1a; NameEditable&am…

统计子矩阵

一、题目描述 P8783 [蓝桥杯 2022 省 B] 统计子矩阵 二、算法简析 2.1 二维前缀和 我们知道&#xff0c;只要确定了矩阵的左上顶点和右下顶点&#xff0c;一个矩阵就被固定了。因此&#xff0c;我们可以遍历这两个顶点&#xff0c;达到遍历所有子矩阵的目的&#xff0c;复杂…

在微服务整合dubbo,以为微服务版的若依为例

在微服务整合dubbo&#xff0c;以为微服务版的若依为例 一、环境二、整合过程1、父模块依赖2、生产者3、消费者 三、修改若依的服务调用方式为dubbo1、改造系统模块2、改造认证授权中心 四、整合过程遇到的问题1、出现循环引用2、出现依赖冲突3、启动出现端口号被占用4、出现某…

UVa11726 Crime Scene

题目链接 UVa11726 - Crime Scene 题意 给定n&#xff08;n≤100&#xff09;个物体&#xff0c;每个物体都是一个圆或者k&#xff08;k≤10&#xff09;边形&#xff0c;用长度尽量小的绳子把它们包围起来。 分析 孟加拉国Manzurur Rahman Khan (Sidky)大神出的难题&#xff…

MySQL 核心模块揭秘 | 07 期 | 二阶段提交 (1) prepare 阶段

二阶段提交的 prepare 阶段&#xff0c;binlog 和 InnoDB 各自会有哪些动作&#xff1f; 本文基于 MySQL 8.0.32 源码&#xff0c;存储引擎为 InnoDB。 1. 二阶段提交 二阶段提交&#xff0c;顾名思义&#xff0c;包含两个阶段&#xff0c;它们是&#xff1a; prepare 阶段。…

springboot-基础-eclipse配置+helloword示例

备份笔记。所有代码都是2019年测试通过的&#xff0c;如有问题请自行搜索解决&#xff01; 下一篇&#xff1a;springboot-基础-添加model和controller的简单例子常用注解含义 目录 配置helloword示例新建项目创建文件 配置 spring boot官方有定制版eclipse&#xff0c;也就是…

BUUCTF AWD-Test1

打开靶场是这个有些简陋的界面。 随便点点&#xff0c;找到这个东西。 看到ThinkPHP&#xff0c;思路瞬间清晰&#xff0c;老熟人了。这个就是ThinkPHP漏洞。根据版本我们去找一下poc。 /index.php/?sIndex/\think\View/display&content%22%3C?%3E%3C?php%20phpinfo();…

服务端向客户端推送数据的实现方案

在日常的开发中&#xff0c;我们经常能碰见服务端需要主动推送给客户端数据的业务场景&#xff0c;比如数据大屏的实时数据&#xff0c;比如消息中心的未读消息&#xff0c;比如聊天功能等等。 本文主要介绍SSE的使用场景和如何使用SSE。 服务端向客户端推送数据的实现方案有哪…

MySQL 自增列解析(Auto_increment)

MySQL数据库为列提供了一种自增属性&#xff0c;当列被定义为自增时。Insert语句对该列即使不提供值&#xff0c;MySQL也会自动为该列生成递增的唯一标识&#xff0c;因此这个特性广泛用于主键的自动生成。 一、自增列的用法 自增列具有自动生成序列值&#xff0c;整型&#…

MYSQL04高级_逻辑架构剖析、查询缓存、解析器、优化器、执行器、存储引擎

文章目录 ①. 逻辑架构剖析②. 服务层 - 查询缓存③. 服务层 - 解析器④. 服务层 - 优化器⑤. 服务层 - 执行器⑥. MySQL8执行原理 ①. 逻辑架构剖析 ①. 服务器处理客户端请求 ②. 连接层 系统(客户端)访问MySQL服务器前,做的第一件事就是建立TCP连接经过三次握手建立连接成…

Linux使用C语言实现通过互斥锁限制对共享资源的访问

互斥锁限制共享资源的访问 主线程中有两个线程&#xff0c;分别输出信息。 #include <stdio.h> #include <pthread.h> #include <unistd.h>int g_data0;void* fun1(void *arg) {printf("t1&#xff1a;%ld thread is create\n", (unsigned long)…

稀疏图带负边的全源最短路Johnson算法

BellmanFord算法 Johnson算法解决的问题 带负权的稀疏图的全源最短路 算法流程 重新设置的每条边的权重都大于或等于0&#xff0c;跑完Djikstra后得到的全源最短路&#xff0c;记得要还原&#xff0c;即&#xff1a;f(u,v) d(u,v) - h[u] h[v] 例题

45、WEB攻防——通用漏洞PHP反序列化POP链构造魔术方法原生类

文章目录 序列化&#xff1a;将java、php等代码中的对象转化为数组或字符串等格式。代表函数serialize()&#xff0c;将一个对象转换成一个字符&#xff1b;反序列化&#xff1a;将数组或字符串等格式还成对象。代表函数unserialize()&#xff0c;将字符串还原成一个对象。 P…

MWC 2024丨Smart Health搭载高通Aware平台—美格发布智能健康看护解决方案,开启健康管理新体验

2月29日&#xff0c;在MWC 2024世界移动通信大会上&#xff0c;全球领先的无线通信模组及解决方案提供商——美格智能正式发布了新一代Cat.1模组SLM336Q&#xff0c;是中低速物联网应用场景的高性价比之选。本次还发布了首款搭载高通Aware™平台的智能看护解决方案MC303&#x…

[万字长文] 从 Vue 3 的项目模板学习 tsconfig 配置

文章目录 一、tsconfig.json 的作用二、基本介绍三、Vue 3 的 tsconfig.json 的结构分析1. 总配置 tsconfig.json2. Web 侧 tsconfig.app.jsona. 继承基础配置b. 包含和排除的文件c. 编译器选项 3. 测试 tsconfig.vitest.jsona. 继承的基础配置b. 包含和排除的文件c. 编译器选项…

OD(13)之Mermaid饼图和象限图

OD(13)之Mermaid饼图和象限图使用详解 Author: Once Day Date: 2024年2月29日 漫漫长路才刚刚开始… 全系列文章可参考专栏: Mermaid使用指南_Once_day的博客-CSDN博客 参考文章: 关于 Mermaid | Mermaid 中文网 (nodejs.cn)Mermaid | Diagramming and charting tool‍‌⁡…