20170731 Shell 脚本编程基础(二)

一、退出状态

  • 进程通过退出状态报告进程运行成功或失败
  • echo $?查看上一条命令执行的退出状态
  • 0代表运行成功,1-255代表运行失败
  • exit [n] 自定义退出状态码
  • 如果未指定退出状态码,脚本运行结束后的退出状态码为执行脚本最后一条命令的退出状态码
  • 实验:
    (一)编写脚本error.sh,代码如下:
# /bin/bash
#
pwd
cmd
exit 100

执行结果如下:

由于没有cmd这条命令,所以脚本运行报错,退出状态码为指定的100。
(二)改动脚本error.sh,改动后的代码如下:

# /bin/bash
#
pwd
cmd
(exit 100)
echo hello

执行结果如下:

发现虽然设置了exit命令,但之后的命令仍然被执行。原因在于将exit命令放置在小括号中,小括号的意义为在当前进程中新增子进程,exit命令的作用变为退出error.sh进程创建的子进程,父进程仍旧正常运行。

二、算术运算

  • 运算符号:+(加),-(减),*(乘),/(除),%(取余),**(乘方)
  • 实现算数运算的方法
    • let var=算术表达式
    • var=$[算术表达式]
    • var=$((算术表达式))
    • var=$(expr arg1 arg2 arg3 ...)
    • declare -i var=算术表达式
    • echo 算术表达式 | bc
  • let用法
  • $[]和$(())用法
  • expr用法
  • declare -i用法
  • 乘法*符号有时需要转义
  • bash内建有随机数生成器$RANDOM,可以用于生成一定范围的随机数,如生成2-50的随机数$[$RANDOM%49+2]
  • 增强型赋值:+=,-=,*=,/=,%=,例如a+=3等于a=a+3,其他符号类似
  • 自增、自减:++,--,例如a++,b--
  • 自增自减运算符在变量前后可能导致不同的结果,运算符在前如++a表示对变量a自增1再进行其他操作,运算符在后如b--表示对变量b先进行其他操作再自减1

三、逻辑运算

  • 逻辑运算的结果只有true或false,但是不同情况下对true或false的数字描述不同
  • 与运算:只有均为true,结果才为true,否则结果均为false
  • 或运算:只有均为false,结果才为false,否则结果均为true
  • 非运算:true取非结果为false,false取非结果为true
  • 短路与 &&:第一个为0,第二个跳过计算,结果一定为0;
    第一个为1,继续计算第二个,才能计算出结果
  • 短路或 ||: 第一个为1,第二个跳过计算,结果一定为1;
    第一个为0,继续计算第二个,才能计算出结果
  • 异或^:相同为假,不同为真,异或可以用于交换两个值

四、条件测试

(一)测试命令

  • test expression
  • [ expression]
  • [[ expression ]]
  • 括号内的expression前后都需要有空格
  • COMMAND1 && COMMAND2,COMMAND1为真时执行COMMAND2
  • COMMAND1 || COMMAND2,COMMAND1为假时执行COMMAND2
  • COMMAND1 && COMMAND2 || COMMAND3,可以实现当COMMAND1执行结果为真时,执行COMMAND2;当COMMAND1执行结果为假时,执行COMMAND3

(二)数值测试

  • -v VAR 变量VAR是否设置

  • -eq 是否等于

  • -gt 是否大于

  • -ge 是否大于等于

  • -lt 是否小于

  • -le 是否小于等于

  • -ne 是否不等于

  • 实验:实现当磁盘利用率超过80%时,自动报警

  • 代码如下:

#! /bin/bash
#
diskusage=`df | grep "/dev/sd" | grep -o "[0-9]\{1,3\}%" | tr -d % | sort -nr | head -1`
[ "$diskusage" -ge 80 ]  && echo "disk will be full"
  • 执行结果如下:

(三)字符串测试

  • == 是否等于
  • > 是否大于
  • < 是否小于
  • != 是否不等于
  • =~ pattern 是否匹配正则表达式,正则表达式为扩展正则表达式
  • -z "string" 字符串是否为空,空为真,非空为假
  • -n "string" 字符串是否非空,非空为真,空为假
  • 字符串测试中的操作数都需要打引号,才能确保结果正确
  • 可以看出变量var非空时为真,空时为假
  • 变量abc为空,测试时使用-n选项应该非空为真,空为假,不会执行第二条命令打印true。但是当变量未有引号包含时,执行打印true,显然不对。变量有引号包含后,第二条命令不运行,符合预期。所以在字符串测试中一定要对变量打引号。

(四)文件测试

  • 存在性测试

    • -a 或-e 存在为真,不存在为假
  • 类别测试

    • -f 是否存在且为普通文件
    • -d 是否存在且为目录文件
    • -h 或 -L 是否存在且为符号链接文件
    • -b 是否存在且为块设备文件
    • -c 是否存在且为字符设备文件
    • -p 是否存在且为管道文件
    • -s 是否存在且为套接字文件
    • 判断文件类型时,遇到软链接文件会直接判断链接的源文件类型,所以要先判断是否为软链接文件
    • 实验:
  • 文件权限测试

    • -r 是否存在且可读
    • -w 是否存在且可写
    • -x 是否存在且可执行
  • 文件特殊权限测试

    • -u 是否存在且拥有suid权限
    • -g 是否存在且拥有sgid权限
    • -k 是否存在且拥有sticky权限
  • 实验:判断文件后缀是否为.sh,若是则判断其是否具有可执行权限,若是则退出,否则为其增加可执行权限

  • 文件大小测试
    • -s 文件是否存在且非空
  • 文件属性测试
    • -O 文件上一次被读取后是否被修改过,即mtime是否新于atime
    • -U 当前用户是否为文件属主
    • -G 当前用户是否为文件属组

(五)双目测试

  • file1 -ef file2 两个文件是否属于相同分区同一个inode号
  • file1 -nt file2 file1是否新于file2,比较mtime
  • file1 -ot file2 file1是否旧于file2,比较mtime
  • 实验:验证两个文件是否同一个inode号

(六) 组合测试

  • 第一种方式:
    COMMAND1 && COMMAND2 并且
    COMMAND1 || COMMAND2 或者
    !COMMAND 非
  • 第二种方式(只在组合测试命令时使用):
    expression1 -a expression2 并且
    expression1 -o expression2 或者
    !expression 非

五、read 将输入分配给一个或多个变量

  • -p 指定要显示的提示
  • -s 静默输入,用于密码输入
  • -n N 指定输入的字符长度N
  • -d char 自定输入的结束符
  • -t N timeout为N秒
  • read从标准输入读入多个单词,每个单词一个变量,若变量个数少于单词数,则多出的单词也赋给最后一个变量
  • 实验

六、bash展开命令行的顺序

  • 把命令行分成单个命令词
  • 展开别名
  • 展开大括号的声明({})
  • 展开波浪符声明(~)
  • 命令替换($()和``)
  • 再次把命令行分成命令词
  • 展开文件通配(*、?、[abc]等等)
  • 准备I/0重导向(<、>)
  • 运行命令

七、bash的配置文件

  • 全局配置文件
    • /etc/profile
    • /etc/profile.d/*.sh
    • /etc/bashrc
  • 个人配置文件
    • ~/bash_profile
    • ~/bashrc
  • 交互式登录:终端输入账号密码登录或者su - username登录
    配置文件执行顺序:/etc/profile -> /etc/profile.d/*.sh -> ~/bash_profile -> ~/bashrc -> /etc/bashrc
  • 非交互式登录:图形终端登录、su username登录、执行脚本
    配置文件执行顺序:~/bashrc -> /etc/bashrc -> /etc/profile.d/*.sh
  • profile类文件配置功能
    • 定义环境变量
    • 运行脚本
  • bashrc类文件配置功能
    • 定义命令别名和函数
    • 定义本地变量
  • 配置文件生效
    • 重启shell进程
    • .或者source

八、bash的退出任务

  • 退出任务保存在~/bash_logout文件中
  • 在退出登录的shell时运行~/bash_logout文件
  • 可用于退出后创建自动备份、清除临时文件等功能

九、$- 变量

  • h:hashall,打开这个选项后,Shell会将命令所在的路径hash下来,避免每次都要查询。通过set +h将h选项关闭
  • i:interactive-comments,包含这个选项说明当前的shell是一个交互式的shell。在脚本中,i选项是关闭的
  • m:monitor,打开监控模式,就可以通过Job control来控制进程的停止、继续,后台或者前台执行等
  • B:braceexpand,大括号扩展
  • H:history,H选项打开,可以展开历史列表中的命令,可以通过!感叹号来完成,例如“!!”返回上最近的一个历史命令,“!n”返回第n 个历史命令
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,830评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,992评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,875评论 0 331
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,837评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,734评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,091评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,550评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,217评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,368评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,298评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,350评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,027评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,623评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,706评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,940评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,349评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,936评论 2 341

推荐阅读更多精彩内容