《Unix/Linux系统编程》第十章读书笔记
自学教材第10章学习笔记
一、任务内容
- 自学教材第10章,提交学习笔记(10分)
大家学习过Python,C,Java等语言,总结一下一门程序设计语言有哪些必备的要素和技能?这些要素和技能在shell脚本中是如何呈现出来的? - 知识点归纳以及自己最有收获的内容 (3分)
- 问题与解决思路(2分)
- 实践内容与截图,代码链接(3分)
- ...(知识的结构化,知识的完整性等,提交markdown文档,使用openeuler系统等)(2分)
二、学习程序设计语言必备的要素和技能
。自主学习能力
- 自主学习可以不仅仅让你自己学会学习,还能激发自己去探索新的问题,然后去针对性地学习新事物。还要有一个创造发明的新思维,因为书本的知识总有一定的局限性,你还要去主动发现新事物和新的学习问题,开阔学习思路。这样可以让你自己学习中创造有利于后代的新知识。在刚开始接触程序语言时,大部分时候都是老师领进门,修行在个人,因为没有充足的课堂时间,所以基本上都是在课下自学。如果没有自主学习的能力,那么就无法透彻的掌握程序设计语言。
- 抽象概括能力
- 程序员经常需要面对、处理异常复杂的业务和逻辑,如果不具备强大的抽象能力,无法把具体变成概念,进而驾驭概念进行思考,那就很难降低问题的复杂度,从而陷入泥潭,无法自拔。无论你学会了多么强大的程序语言,你的编程能力也很难有质的提高。我们只有从纷繁复杂的现象中抽取事物的本质,从具体事物提炼出正交的概念,才能驾驭这些概念,才能在一个低复杂度的世界中进行思考。
- 拆解问题能力
- 当我们遇到问题时,如果能力大于问题,直接用能力解决。
当能力小于问题,我们该怎么办呢?
有两大方法可以解决问题:
1)降低问题难度。将问题的难度降低到自己的能力之下,这样能力大于问题难度,问题就可以解决了。
2)提高解决问题的能力。提高自己解决问题的能力,使得能力大于问题的难度,这样问题也可以解决。
这就是拆分问题的精髓,因为在学习程序语言的时候能力有限,大部分时候都不能很顺利的直接解决问题,所以需要使用分而治之的方法,把困难的问题拆分成多个简单的问题。
这些要素和技能在shell脚本中是如果呈现出来的?
- 通过前期对即将编写的shell脚本的需求了解;
- 通过对即将编写的shell脚本的总体框架构建;
- 通过对编写过程中遇到问题的自我学习解决;
- 通过对编写完后对shell脚本的调试解决;
三、知识归纳
思维导图
知识归纳
sh脚本
- sh脚本是一个包含sh语句的文本文件,命令解释程序sh要执行该语句,使用chmod +x xx.sh使其可执行,之后运行sh文件。
- sh脚本的第一行通常以#!组合开始,称为shebang。若未指定shebang,则运行默认sh即/bin/bash。
实验操作
-
在虚拟机中打开终端,输入emacs进入后,新建a.sh文本文件,输入代码
- 在终端中输入bash a.sh实现代码功能
-
sh脚本与C程序
sh脚本和C程序有一些相似之处,但在根本上是不同的
对于sh:
- sh是一个解释程序,逐行读取sh脚本文件并直接执行这些行;
- sh脚本中的每个变量都是字符串;
- sh脚本中的第一个可执行语句是程序的入口点;
对于C程序:
- C程序需要先编译链接到一个二进制可执行文件,之后通过主sh子进程运行二进制可执行文件;
- C程序中的每一个变量必须有一个类型;
- C程序需要有一个mian()函数作为入口点
-
命令行参数
-
在sh脚本中,可以通过位置参数$0、$1、$2等访问命令行参数。前10个命令行参数可以作为$0~$9被访问。其他参数必须称为${10}~${n},其中n>10。或者,可以通过稍后显示的shift命令查看它们。通常,$0是程序名本身,$1到$n是程序的参数。在sh中,可用内置变量$#和$*计数并显示命令行参数。
S#=命令行参数$1到$n的数量
$*=所有命令行参数,包括$0
此外,sh还有与命令执行相关的以下内置变量。
$S =执行sh的进程PID
$?=最后一个命令执行的退出状态(如果成功,则为0,否则为非0)
在sh中,特殊字符$表示替换,注意需要添加转义符‘\’。
-
实践:
因为题目中mysh脚本是假设初始值的,所以运行结果与期望值不符
所以在终端输入时,需初始化符号内容,即可实现功能。
sh变量
shell编程中有两种变量,一种是我们自己定义的变量(自定义变量),可以通过set命令查看系统变量;第二种是Linux已定义的环境变量(如 PATH,HOME,TERM等等……这类变量我们可以直接使用) 需要记住的是:定义变量不用[$]符号,使用变量加符号即可。
在自定义变量时,如果变量出现空格或者引号,那么也必须加引号,否则就可以省略。格外需要注意的是,自定义变量的时候,“=”左右不能有空格。sh中的引号
sh有许多特殊字符,如S、/、*、>、<等。要想把它们用作普通字符,可使用\或单引号来引用它们。通常,‘\’用于引用单个字符。单引号用于引用长字符串。单引号内没有替换。双引号用于保留双引号字符串中的空格,但在双引号内会发生替换。sh语句
sh语句包括所有Unix/Linux命令,以及可能的I/O重定向。此外,sh编程语言还支持控制sh程序执行的测试条件、循环、case等语句。sh命令
- 内置命令
sh有许多内置命令,这些命令由sh执行,不需要创建一个新进程。
下面列出一些常用的内置sh命令。
- .file :读取并执行文件。
- break [n]:从最近的第 n 个嵌套循环中退出。
- cd [dirname]:更换目录。
- continue [n]:重启最近的第 n 个嵌套循环。
- eval [arg...]:计算一次参数并让sh执行生成的命令。
- exec [arg...]:通过这个 sh 执行命令, sh 将会退出。
- exit[n]:使 sh 退出,退出状态为 n 。
- export [var...]:将变量导出到随后执行的命令。
- read [var...]:从 stdin 中读取一行并为变量赋值。
- set [arg...]:在执行环境中设置变量。
- shift :将位置参数&amp;lt;span id="MathJax-Span-15" class="mrow"&amp;gt;&amp;lt;span id="MathJax-Span-16" class="mn"&amp;gt;2&amp;lt;span class="MJX_Assistive_MathML"&amp;gt;23...重命名为&amp;lt;span class="MathJax_Preview"&amp;gt;&amp;lt;span id="MathJax-Element-5-Frame" class="MathJax" data-mathml="&amp;amp;lt;math xmlns=&amp;amp;quot;http://www.w3.org/1998/Math/MathML&amp;amp;quot;&amp;amp;gt;&amp;amp;lt;mn&amp;amp;gt;1&amp;amp;lt;/mn&amp;amp;gt;&amp;amp;lt;/math&amp;amp;gt;"&amp;gt;&amp;lt;span id="MathJax-Span-17" class="math"&amp;gt;&amp;lt;span id="MathJax-Span-18" class="mrow"&amp;gt;&amp;lt;span id="MathJax-Span-19" class="mn"&amp;gt;1&amp;lt;span class="MJX_Assistive_MathML"&amp;gt;12...
- trap [arg[n]:接收到信号 n 后执行参数。
- umask [ ddd ]:将掩码设置为八进制数 ddd 的。
- wait [pid];等待进程 pid ,如果没有给出 pid ,则等待所有活动子进程。
- read 命令:当 sh 执行 read 命令时,它会等待来自 stdin 的输入行。它将输人行划分为几个标记,分配给列出的变量。
Linux命令
- echo:将参数字符串作为行回显到stdout,通常将多个空格压缩为一个(除非有引号);
- expr:用于在UNIX/LINUX下求表达式变量的值,一般用于整数值,也可用于字符串;
I = 123 I = $(expr $I +1)
实用命令:
- awk:数据处理程序;
- cmp:比较两个文件;
- comm:选择两个排序文件共有的行;
- grep:匹配一系列文件的模式;
- diff:找出两个文件的差异;
- join:通过使用相同的键来连接记录以比较两个文件;
- sed:流或行编辑命令;sort:排序或合并文件;
- tail:打印某个文件的最后n行;
- tr:一对一字符翻译;
- uniq:从文件中删除连续重复行。
命令替换:
当sh遇到'cmd'或$(cmd)时,会优先执行cmd,并用执行结果字符串替换cmd。
命令分组:
在sh脚本中,使用{}或()对命令进行分组;
{}:在相同环境下执行{}中的命令;
():通过subsh进程执行()中的命令,subsh进程可在不影响父sh的情况下更改其工作目录;
sh控制语句
- 在sh中每个语句需单独在一行上,若用分号将多个语句隔开,则运行多个语句在同一行;
- 在sh中0为TRUE,而非0为FALSE;
if-else-fi语句
if [condition]; then statements else statements fi
字符串比较:
if [s1 = s2] if [s1 != s2] if [s1 \< s2] if [s1 \> s2]
作为整数比较:
-eq #等于 -ne #不等于 -gt #大于 -lt #小于 -ge #大于等于 -le #小于等于
文件比较:
if [ -x name]
-e filename #如果 filename存在,则为真 -f filename #如果 filename为常规文件,则为真 -d filename #如果 filename为目录,则为真 -r filename #如果 filename可读,则为真 filename1 -ef filename2 #如果 filename1与filename2相同,则为真
if-elif-else-fi复合语句:
if [condition1]; then statements elif [condition]; then statements #additional elif[condition3]; then ..... else statements fi
for语句
每次迭代中,变量接受一个参数字符串值,并执行do和done之间的命令
for VARIABLE in string1 string2 ... stringn do statements done
while语句
当条件为真时,重复执行do-done语句,直至为假时退出
while [condition] do statements done
until-do语句
当条件为真时退出循环
until [condition] do statements done
I/O重定向
.>file stdout转向文件,如果文件不存在,将会创建文件
.>>file stdout追加到文件
<file 将文件用作stdin;文件必须存在具有r权限
<<word 从“here”文件中获取输入,直到包含“word”的行
sh中的通配符
- file *:列出当前目录中所有文件的信息
- ls *.c:列出当前目录中所有以.c结尾的文件
- ?通配符:查询某文件名中的字符
- []通配符:查询文件名中一对[]中的字符
- file ???:有三个字符的所有文件名
- ls *.??:点号后有2个字符的所有文件名
- file [ab]:包含字符a或b的所有文件名
- ls [xyz]:列出所有包含x、y或z的文件名
- ls [a-m]:列出包含a到m范围内字符的所有文件名