sh编程
sh脚本
包含sh语句的文本文件,命令解释程序sh要执行该语句。
sh脚本与C程序
-
sh:解释程序,逐行读取sh脚本文件并直接执行,若行是可执行命令且为内置命令,则可直接执行。不能执行的情况则复刻一个子进程来执行命令,子进程终止后再继续。(只有字符串类型,不需要main函数)
-
C程序:编译为一个二进制可执行文件,通过主sh的子进程运行二进制可执行文件。(必须给变量定义一个类型,需要main函数)
命令行参数
在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中,特殊字符$表示替换,注意需要添加转义符‘\’。
sh变量
-
内置变量:PATH、HOME、TERM
-
任何符号,未赋值的为NULL
-
变量设置或赋值
variable=string
sh中的引导
用\或单引号来把$、/、*、>、<等用作普通字符。
A=xyz
echo $A
echo '$A'
echo "see $A"
sh语句
-
所有Unix/Linux命令
-
可能的I/O重定向
sh命令
1.内置命令
.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:将位置参数$2 $3...重命名为 $1 $2...。
trap [arg] [n]:接收到信号n后执行参数。
umask [ddd]:将掩码设置为八进制数 ddd 的。
wait pid]: 等待进程 pid,如果没有给出pid,则等待所有活动子进程。
read命令:当sh执行read命令时,它会等待来自stdin的输入行。
2.Linux命令
-
echo命令:echo只是将参数字符串作为行回显到stdout。通常将相邻的多个空格压缩为一个空格,除非有引号。
-
expr命令:将两个参数字符串转换为数字,然后对数字执行(二进制)操作OP,再将得到的数字转换回字符串。
expr string1 OP string2
-
管道命令:在sh脚本中经常使用管道作为过滤器。
-
实用命令:
axk:数据处理程序。
cmp:比较两个文件。
comm:选择两个排序文件共有的行。
grep:匹配一系列文件的模式。
diff:找出两个文件的差异。
join:通过使用相同的键来连接记录以比较两个文件。
sed:流或行编辑命令。
sort:排序或合并文件。
tail:打印某个文件的最后口行。
tr:一对一宇符翻译。
uniq:从文件中删除连续重复行。
命令替换
echo $(date)
echo $(ls dir)
sh控制语句
sh是一种编程语言,支持许多执行控制语句,类似于C语言中的语句。
1.if-else-fi语句
if [condition]
then
statemates
else
statements
fi
每个语句必须在单独的一行(要写到同一行也可以在多个语句之间用分号分开)
2.for语句
for VARIABLE in string1 string2 ... stringn
do
commands
done
类似C语言中的for循环
3.while语句
while [condition]
do
commands
done
类似C语言中的while循环
4.until-do语句
until [$ANS = "give up"]
do
echo -n "enter your answer"
read ANS
done
类似C语言中的do-until语句
5.case语句
case $variable in
pattern1) commands;;
pattern2) command;;
patternn) command;;
esac
6.continue和break语句
-
continue:重启最近循环的下一个迭代。
-
break:退出最近循环。
工作原理与C语言完全相同
I/O重定向
-
>file:stdout转向文件,如果文件不存在,将会创建文件。
-
>>file:stdout追加文件。
-
<file:将文件用作stdin;文件必须存在并具有r权限。
-
<<word:从“here”文件中获取输入,直到包含“word”的行。
sh函数
func()
{
# function code
}
sh中的通配符
1.星号通配符:可扩展到当前目录中的所有文件,是最有用的通配符。
file *:列出当前目录中所有文件的信息。
ls *.c:列出当前目录中所有以.c结尾的文件。
2.?通配符:查询某文件名中的字符。
file ???:有三个字符的所有文件名。
ls *.??:点号后有2个字符的所有文件名。
3.[]通配符:查询文件名中一对[]中的字符。
file *[ab]*:包含字符a或b的所有文件名。
ls *[xyz]*:列出所有包含x、y或z的文件名。
ls *[a-m]*:列出包含a到m范围内字符的所有文件名。
问题与解决思路
问题:
在使用for循环遍历当前目录下的每个文件名时,若文件名有空格就不能正确输出带空格的文件名,而是把带空格的文件名字分开来输出。
比如文件名为x y z.txt,则输出为三个文件:
x
y
z.txt
解决思路:
使用*通配符就可以匹配所有txt后缀的文件名。如果当前目录没有匹配的文件名,就增加一个判断语句来进行判断,如果不是文件,则跳过,继续循环下一个。