第十章 sh编程
概要
阐述了sh脚本和不同版本的sh;比较了sh脚本与C程序,并指出了解释语言和编译语言的区别;如何编写sh脚本,包括sh变量、sh语句、sh内置命令、常规系统命令和命令替换;解释了sh控制语句,其中包括测试条件、for循环 while循环 do-until循环、case语句等,并示范了它们的用法;说明了如何编写sh函数以及使用参数调用sh函数;还举例说明了sh脚本的广泛应用,包括Linux系统的安装、初始化和管理。
sh脚本
是一个包含sh语句的文本文件、命令解释程序sh要执行该语句。
sh有不同的版本,例如Linux的bash
#! /bin/bash
# comment line
echo hello
sh脚本与C程序
sh脚本 | C程序 |
---|---|
sh是一个解释程序,逐行读取sh脚本文件并直接执行这些行。如果行是可执行命令且为内置命令,那么sh可直接执行。否则,它会复刻一个子进程来执行命令,并等待子进程终止后再继续,这与它执行单个命令行完全一样 | C程序必须先编译链接到一个二进制可执行文件,然后通过主sh的子进程运行二进制可执行文件 |
在sh脚本中,每个变量都是字符串。因此不需要类型,因为只有一种类型,即字符串 | 在C程序中,每个变量必须有一个类型,例如char int、float、派生类型(如struct)等 |
sh脚本不需要main函数。在sh脚本中,第一个可执行语句是程序的人口点。 | 每个C程序必须有一个main()函数,每个函数必须定义一个返回值类型和参数(如有) |
命令行参数
$#=命令行参数\(1到\)n的数量
$*=所有命令行参数,包括\(0
此外,sh还有与命令执行相关的以下内置变量。
\)S=执行sh的进程PID
$?=最后一个命令执行的退出状态(如果成功,则为0,否则为非0)
sh变量
sh有愈多内置变量,如PATH、HOME、TERM等。除了内置变量外,用户还可以使用任何符号作为sh变量,不需要声明
sh命令
内置命令
.file | 读取并执行文件 |
---|---|
break[n] | 从最近的第n个嵌套循环中退出 |
ocd[dirname] | 更换目录 |
continue[n] | 重启最近的第n个嵌套循环 |
eval[arg…] | 计算一次参数并让sh执行生成的命令 |
exec[arg…] | 通过这个sh执行命令,sh将会退出 |
exit[n] | 使sh退出,退出状态为n |
export[var…] | 将变量导出到随后执行的命令 |
read[var…] | 从stdin中读取一行并为变量赋值 |
set[arg…] | 在执行环境中设置变量 |
shift | 将位置参数$2$3…重命名为$1$2 |
etrap[arg][n] | 接收到信号n后执行参数 |
umask[ddd] | 将掩码设置为八进制数ddd的 |
wait[pid] | 等待进程pid,如果没有给出pid,则等待所有活动子进程 |
read命令
当sh执行read命令时,它会等待来自stdin的输入行。它将输入行划分为几个标记,分配给列出的变量。read的一个常见用法是允许用户与正在执行的sh进行交互。
Linux命令
echo命令
echo只是将参数字符串作为行回显到stdout。它通常将相邻的多个空格压缩为一个空格,除非有引号
expr命令
因为所有的sh变量都是字符串,所以我们不能直接把我们改为数值
I=123 #I assigned the string"123"
I=I+1#Iassigned thestring"I+1"
#! /bin/bash
i=123
echo $i
i=$i+1
echo $i
i=123
i=$(expr $i + 1)
echo $i
最后一个语句并不是将I的数值增加1,而仅仅是将1更改为字符串“I+1”,这肯定不是我们所希望的结果(I=124)。可通过expr命令间接更改sh变量的值(数值)。expr是一个程序,它的运行方式如下:
expr string1 op string2#OP=anybinary operator on numbers
首先,它将两个参数字符串转换为数字,然后对数字执行(二进制)操作OP,再将得到的数字转换回字符串。因此,
I=123
I=$(expr$I+1)
将I从“123”更改为“124”。同样,expr也可用于对其值为数字字符串的sh变量执行其他算术操作。
管道命令:在sh脚本中经常使用管道作为过滤器。
实用命令
awk:数据处理程序。
cmp:比较两个文件。
comm:选择两个排序文件共有的行。
grep:匹配一系列文件的模式。
diff:找出两个文件的差异。
join:通过使用相同的键来连接记录以比较两个文件
sed:流或行编辑命令。
sort:排序或合并文件。
tail:打印某个文件的最后n行。
tr:一对一字符翻译。
uniq:从文件中删除连续重复行。
命令替换
在sh中,$A会被替换成A值,当sh遇到‘cmd’或$(cmd)时,她会先执行cmd,然后用执行的结果字符串替换$(cmd)
if-else-fi 语句
if [condition]; then
statements
else
statements
fi
#! /bin/bash # employ bash shell
if [ "$1" = "me" ]; then
echo "You are female..."
else
echo "$1 is male..."
fi
for语句
在每次迭代中,变量接受一个参数字符串值,并执行关键字do和done之间的命令
for VARIABLE in string1 string2 ... stringn
do
connands
done
while语句
while[condition]
do
commands
done
#! /bin/bash
i=7
j=10
while [ $i -lt $j ]
do
echo "num1 = $i, num2=$j"
((i++))
done
until-do
until [ $ANS="give up"]
do
echo -n "enter your answer:"
read ANS
done
case语句
case $variable in
pattern1) commands;; # note the double semicolonsji;;
pattern2) command;;
patternN) command;;
esac
continue和break语句
continue重启最近循环的下一个迭代,break退出最近循环
I/O重定向
>file stdout转向文件,如果文件不存在,将会创建文件。
>> file stdout追加到文件。
< file 将文件用作stdin;文件必须存在并具有r权限。
<<word 从“here”文件中获取输人,直到只包含“word”的行。
嵌入文档
可以指示输出命令从stdin获取输入,将其回显到stdout,指导遇到预先安排的关键字
echo << END
# keep enter and echo lines until a line with only END
cat << DONE
# keep enter and echo lines until DONE
sh中的通配符
星号通配符:sh中最有用的通配符是,可扩展到当前目录中的所有文件。示例10.14:
·file:列出当前目录中所有文件的信息。
·lsc:列出当前目录中所有以c结尾的文件。?通配符:查询某文件名中的字符示例10.15:
file???:有3个字符的所有文件名。
·ls??:一个点号.后有2个字符的所有文件名。[1通配符:查询文件名中一对日中的字符。示例10.16:
·file[ab]:包含字符a或b的所有文件名。·Is[xyz]:列出所有包含x、y或z的文件名。
·ls[a-m]:列出包含a到m范围内字符的所有文件名。
问题:if语句后面的[和]的左右空格没打出现报错
解决:https://blog.csdn.net/donkeyfan/article/details/6280163