shell程序设计入门(三)
- 导语
- 命令
- 简单命令
- break
- :命令
- continue
- echo
- eval
- exec
- exit
- expr
- printf
- return
- shift
- 复杂指令
- .
- export
- set
- unset
- trap
- find
- grep
- 总结
- 参考文献
导语
本篇介绍一些shell中常用的复杂命令及其使用,如set、echo、expr等命令
命令
简单命令
break
shell中的break和C语言中的break起到的作用一样,都是跳出当前循环或者判断
for file in *
do
if [ -f "$file" ];then
break;
fi
done
:命令
冒号命令是一个空命令,用于简化条件逻辑,等同于true,运行比true快,也就是可以可用while :来进行死循环
:也被用在变量的条件设置中,如下
: ${var:=value}
意思是:如果 var 没有被定义或者为空,则将 var 设为 value,否则var不变
这行命令放在C语言中的实现类似于
var=var?var:value;
continue
和C语言中的意义一样,都是跳过当前循环,直接进入下一次循环
echo
echo是最简单的输出语句,可以通过添加参数来删去换行符
echo -n "aaa"
echo -e "aaa\c"
两种命令用了不同的参数,但实现的效果是一样的,后者确保启用了转义字符(\c是去掉换行符)
eval
eval允许对参数求值,这样将表达式从字符串中解放出来,它有点像一个额外$,给出一个变量的值的值
exec
exec很少用,这里直接给出书上的解释
exit
exit很简单,将脚本以退出码n结束运行,0认为是成功,其他的数字在Linux中各有含义,通过捕获退出码可以查看脚本出现了什么问题
expr
expr和eval有类似的地方,它们都是得到值,但是expr是将参数作为表达式来求值,并且expr支持的表达式更多,而eval只支持单个的参数
x='expr $x + 1'
x=$(expr $x +1)
#两者都实现了x++
printf
shell的printf使用和C语言的使用大部分都重合,区别是前者不支持浮点数,并且输出的时候不带括号和逗号,只用空格分开
printf "%d" 15
return
与C语言相同,return起到返回函数的返回值的作用,但是shell中的return和exit大不一样,前者的对象是函数,后者的对象是整个脚本程序,并且后者的返回值会被捕获作为错误码
shift
shift把参数列表中所有的参数左移一个位置,除了$0,也就是1234变成了234,后者取代了前者的位置。如果shift -n,那么就相当于参数列表整体左移多少单位,shift会影响到$*等变量
复杂指令
.
.用于在当前shell中执行命令,它的作用类似于C语言中的include,在使用.的时候,执行脚本列出的命令,使用的是与当前脚本程序一样的shell
书上给出的具体论述如下
简单来说,.命令使得脚本相互调用的时候可以操作共同的“全局变量”
export
export将自己的参数作为新的参数导入到子shell当中,实现方式是把参数列为环境变量(类似C语言全局变量),其他的子shell都可以用,具体例子和结果如下
#!/bin/sh
#export2
echo "$foo"
echo "$bar"
#!/bin/sh
#export1
foo="没有加上export前"
export bar="加上export后"
/bin/sh export2
可以看到导出的bar作为了export2的参数
set
set为shell设置参数变量,一般来说,shell命令的输出结果是空格分割的值域(如ls的每行输出有用户名,访问权限,时间等),这个时候就可以通过set拿到输出的某个值域,前提是知道值域的名字或位置,下面是一个简单的输出年份的例子
echo the date is $(date)
set $(date)#拿到date命令的输出
echo $1
exit 0
准确来说,date命令的结果成为了参数列表,然后$1取参数列表的第1个数值
这里是set的简单用法,set加上各种参数还有更多复杂的用法
unset
与set相反,unset就是从环境中删除变量和函数,对象是用户自己定义的变量和函数,不能是shell的,下面是一个简单的例子,可以看到变量被删除了,需要注意的是,直接对f赋值f还是存在的,但是使用unset,f就不存在了
f="1111 222"
echo $f
unset f
echo $f
trap
trap用于设定接受信号后进行的动作,有点类似QT槽的概念,在使用的时候会设定好一个待接收的型号,然后如果程序运行时在交互中出现了对应信号,trap就会执行对应的动作,trap有两个参数,一个是收到信号后采取的行动,另一个是要处理的信号名字,下面是书上给出的例子
#!/bin/bash
trap 'rm -f /tmp/my_tmp_file_$$' INT# INT是中断
echo creating file /tmp/my_tmp_file_$$
date > /tmp/my_tmp_file_$$
echo "press interrupt (CTRL-C) to interrupt ...."
while [ -f /tmp/my_tmp_file_$$ ]; do
echo File exists
sleep 1
done
echo The file no longer exists
trap INT
echo creating file /tmp/my_tmp_file_$$
date > /tmp/my_tmp_file_$$
echo "press interrupt (control-C) to interrupt ...."
while [ -f /tmp/my_tmp_file_$$ ]; do
echo File exists
sleep 1
done
结果如下
这里直接给出书上的解释
find
用于搜索文件的命令,有很多参数,它的语法格式如下
find [path] [options] [tests] [actions]
几个参数分别是路径,选项(如depth,follow),测试(添加的文件判断,如type c,user username),动作(如print、ls),具体见书或手册
以下面这个命令及其结果为例
find . -newer signal_deal -type f -exec ls -l {} \;
这里说明一下命令的意思,-newer signal_deal意思是,搜索的文件要比signal_deal要新,-type f意思是搜索的文件需要是普通文件,-exec ls -l {} ;意思是对搜索结果执行ls -l的动作,总的来说,该命令的意思就是搜索当前目录下的所有文件,找到其中比signal_deal新且是普通文件的文件,并显示它们的详细信息
grep
grep的全称是通用正则表达式解析器,它用来在文件中搜索字符串,它通常和find结合起来使用,grep的使用格式如下,没有提供文件名的情况下,grep将以stdin作为输入
grep [options] PATTERN [FILES]
grep和正则表达式息息相关,这里不多描述,因为正则表达式的用法非常复杂多样,具体的见书上和册子,这里只给出书上一个例子并解析
grep -E [a-z]\{3\} unset_test
该命令在unset_test中找到全部由小写字母组成的长度不小于3的字符串
总结
本篇介绍了shell中的一些常用的命令以及对应的简单用法,并且对例子进行了实机操作和解析,但是这只能说是对shell命令的入门,具体的、更高级的使用需要更深入的学习
参考文献
- 《Linux程序设计(第4版)》