2017-7-31 Shell脚本编程基础

一.编程基本概念

编程逻辑处理方式: 顺序执行 循环执行 选择执行 
shell编程:过程式、解释执行
编程语言的基本结构: 各种系统命令的组合
数据存储:变量、数组 表达式: a + b 语句:if
程序:指令+数据 
程序编程风格:
过程式:以指令为中心,数据服务于指令
对象式:以数据为中心,指令服务于数据 
shell程序:提供了编程能力,解释执行
shell脚本: 包含一些命令或声明,并符合一定格式的文本文件 
格式要求:首行shebang机制 #!/bin/bash #!/usr/bin/python #!/usr/bin/perl 
shell脚本的用途有: 
自动化常用命令  执行系统管理和故障排除  创建简单的应用程序  处理文本或文件

二.创建shell脚本

第一步:使用文本编辑器来创建文本文件  第一行必须包括shell声明序列:#! #!/bin/bash  添加注释 注释以#开头


image.png

第二步:运行脚本  给予执行权限,在命令行上指定脚本的绝对或相对路径  直接运行解释器,将脚本作为解释器程序的参数运行——chmod +x a.sh:加上执行权限
image.png

如上图所示,在脚本中已经加入了cd切换命令,并显示当前目录,但是在下图中,不同的执行命令,显示的结果却不相同——"通过相对路径和bash的执行方式的效果,只在脚本内部有效,并不影响外部 但是source执行方式,既对脚本内部生效,也对脚本外部有效"
image.png

例子:在脚本外部定义,变量名字为mage,在脚本内部定义变量名为wang 结果显示内部脚本命令并不影响外部定义的变量


image.png
image.png

(3)脚本规范
脚本代码开头约定
1、第一行一般为调用使用的语言
2、程序名,避免更改文件名为无法找到正确的文件
3、版本号
4、更改后的时间

5、作者相关信息
6、该程序的作用,及注意事项
7、最后是各版本的更新简要说明
(4)简单的基础脚本的编写——显示"hello my friends"


image.png

image.png

(5)脚本调试
检测脚本中的语法错误 bash -n /path/to/some_script 
调试执行 bash -x /path/to/some_script
image.png

(6)变量
变量:命名的内存空间
数据存储方式: 字符: 数值:整型,浮点型 
变量:变量类型
作用: 1、数据存储格式 2、参与的运算 3、表示的数据范围
类型: 字符 数值:整型、浮点型
强类型:变量不经过强制转换,它永远是这个数据类型,不 允许隐式的类型转换。一般定义变量时必须指定类型、参与 运算必须符合类型要求;调用未声明变量会产生错误 ——如 java,c# 
弱类型:语言的运行时会隐式做数据类型转换。无须指定类 型,默认均为字符型;参与运算会自动进行隐式类型转换; 变量无须事先定义可直接调用
如:bash
不支持浮点数,php 
变量命名法则:

1、不能使程序中的保留字:例如if, for
2、只能使用数字、字母及下划线,且不能以数字开头
3、见名知义
4、统一命名规则:驼峰命名法
大驼峰:每个单词首字母都是大写
小驼峰的命名方法:第一个单词的首字母是小写,后面单词首字母都是大写
(7)bash中变量的种类
根据变量的生效范围等标准:

  • 本地变量
    生效范围为当前shell进程;对当前shell之外 的其它shell进程,包括当前shell的子shell进程均无效
    变量赋值:name='value'——name=mage
    可以使用引用value:
    (1) 可以是直接字串; name="root"
    (2) 变量引用:name="$USER"
    (3) 命令引用:name=COMMAND name=$(COMMAND) ——name=hostname
    变量引用:${name}
    $name "":弱引用,其中的变量引用会被替换为变量值
    '':强引用,其中的变量引用不会被替换为变量值,而保 持原字符串 
    显示已定义的所有变量:set 
    删除变量:unset name
    image.png

    在一个终端窗口定义变量
    image.png

    但是在另一个终端窗口不显示变量名
    image.png

    通过pstree -p来查看进程编号,可以看出进程号并不一样,生效范围只是本地变量有效
    image.png
  • 环境变量:生效范围为当前shell进程及其子进程
    变量声明、赋值: export name=VALUE declare -x name=VALUE 
    变量引用:$name, ${name} 
    显示所有环境变量: env printenv export declare -x 
    删除变量: unset name
    image.png

    在b.sh文件中定义
    image.png

    最后子进程可以实现对父进程内容的调用
    image.png

    但是父进程不能去继承子进程新定义的变量的内容
    image.png

    image.png
  • 位置变量:$1, $2, ...来表示,用于让脚本在脚本代码 中调用通过命令行传递给它的参数
    位置变量:在脚本代码中调用通过命令行传递给脚本的参数
    $1, $2, ...:对应第1、第2等参数——vim f11.sh
    image.png
    image.png

    shift [n]——换位置
    image.png
    image.png

    $0: 命令本身——vim f11.sh
    image.png
    image.png

    $: 传递给脚本的所有参数,全部参数合为一个字符串
    image.png
    image.png
    image.png

    $@: 传递给脚本的所有参数,每个参数为独立字符串
    image.png
    image.png

    $#: 传递给脚本的参数的个数
    image.png
    image.png

    $@ $
    只在被双引号包起来的时候才会有差异
    set -- 清空所有位置变量
  • 特殊变量:$?, $0, $*, $@, $#,$$
  • 只读和位置变量
    只读变量:只能声明,但不能修改和删除 
    声明只读变量:
    readonly name declare -r name 
    查看只读变量:
    readonly –p
    (8)退出状态
    进程使用退出状态来报告成功或失败

    0 代表成功
    image.png

    1-255代表失败 $? 变量保存最近的命令退出状态 
    image.png
  • bash自定义退出状态码

    exit [n]:自定义退出状态码 )
    image.png
    image.png

    注意:脚本中一旦遇到exit命令,脚本会立即终止;终止退出 状态取决于exit命令后面的数字

    注意:如果未给脚本指定退出状态码,整个脚本的退出状态码 取决于脚本中执行的最后一条命令的状态码
    image.png
    image.png

    在编辑脚本的时候,给exit添加一个小括号,代表的意思是给自己开了一个子进程,所以不会影响接下来的命令
    image.png
    image.png

三.算术运算

bash中的算术运算:help let
+, -, *, /, %取模(取余), **(乘方)
实现算术运算:

  • (1) let var=算术表达式
    [root@centos7 ~]#a=20 [root@centos7 ~]#b=30 [root@centos7 ~]#c=$a+$b [root@centos7 ~]#let c=$a+$b [root@centos7 ~]#echo $c 50
    (2) var=$[算术表达式]——var=$[a+b] echo $var
    image.png

    (3) var=$((算术表达式)) ——echo $((a+b))
    (4) var=$(expr arg1 arg2 arg3 ...)——支持数字运算
    image.png
    (5) declare –i var = 数值
    image.png

    (6) echo ‘算术表达式’ | bc ——计算从1加到100
    image.png

    乘法符号有些场景中需要转义,如* 
    bash有内建的随机数生成器:$RANDOM(0-32767)
    echo $[$RANDOM%50] :0-49之间随机数
  • 赋值

增强型赋值: +=, -=, *=, /=, %= 
let varOPERvalue
例如:let count+=3 自加3后自赋值 ——let a+= 5 相当于a=a+5
自增,自减:
let var+=1

let var++ ——
image.png
image.png

let var-=1
let var-
  • 逻辑运算

true, false 1, 0 
与: 全是1结果为1,有0则是0
1 与 1 = 1 1 与 0 = 0 0 与 1 = 0 0 与 0 = 0 
或:有1则为1,全0则是0
1 或 1 = 1
1 或 0 = 1
0 或 1 = 1
0 或 0 = 0
非:!就是取反
! 1 = 0
! 0 = 1 
短路运算
短路与 第一个为0,结果必定为0 ——cmd1 &&cmd2:cmd1为假的时候,不去执行后面的命令,结果也为假
第一个为1,第二个必须要参与运算 ——cmd1 && cmd2:cmd1为真的时候,去执行cmd2,cmd2为真的时候,结果为真,cmd为假的时候,结果为假
短路或 第一个为1,结果必定为1——cmd1 || cmd2:cmd1为真的时候,不去执行cmd2,结果为真
cmd2第一个为0,第二个必须要参与运算 ——cmd1为假的时候,cmd2为真的时候,去执行cmd2 ,结果为真,cmd2为假的时候,结果为假
异或:^ 异或的两个值,相同为假,不同为真

例子:当a=5,b=8时,通过异或实现a与b的互换
image.png
  • 条件测试

(1) 判断某需求是否满足,需要由测试机制来实现 专用的测试表达式需要由测试命令辅助完成测试过程

(2) 测试命令: test EXPRESSION
image.png

例1:如果比较两个值相等,则输出结果显示为'equal',可以采用短路与来实现 a=xcv,b=xcv
image.png

例2:此时,改变b的值,让其不等于a,那么采用短路或实现输出结果为'not equal'


image.png

[ EXPRESSION ] =等价test变量
image.png

在test测试用法中空字符等同于没有赋值,而给变量赋值0或是空格,就是赋值输出结果为真
image.png

test:
-n:非空为真判断变量是否为空一定要加双引号
image.png

-z:空为真当给sdc赋值后,不再为空,那么空为假,则不执行下面的命令
image.png
  • 数值测试:

-gt 是否大于
-ge 是否大于等于
-eq 是否等于
-ne 是否不等于
-lt 是否小于
-le 是否小于等于

例1:
image.png

例2:
image.png

例3:读取磁盘分区利用率,如果利用率大于10则报警
image.png
  • 字符串测试:

"在没有赋值的时候,给字符串加上引号"
== 是否等于 > ascii码是否大于ascii码
< 是否小于 != 是否不等于
=~ 左侧字符串是否能够被右侧的PATTERN所匹配 注意: 此表达式一般用于[[ ]]中扩展的正则表达式
[[ EXPRESSION ]] ——支持正则表达式


image.png

注意:EXPRESSION前后必须有空白字符,在正则表达式中,字符串不用加引号
image.png

四.Bash的文件测试

(1)存在性测试
-a FILE:同-e
-e FILE: 文件存在性测试,存在为真,否则为假 


image.png

存在性及类别测试

-b FILE:是否存在且为块设备文件
image.png

-c FILE:是否存在且为字符设备文件
image.png

-d FILE:是否存在且为目录文件
-f FILE:是否存在且为普通文件

-h FILE 或 -L FILE:存在且为符号链接文件 ——判断文件类型的时候先判断该文件是否为软连接
image.png

image.png

-p FILE:是否存在且为命名管道文件
-S FILE:是否存在且为套接字文件
(2)Bash的文件权限测试
文件权限测试:
-r FILE:是否存在且可读
image.png

-w FILE: 是否存在且可写
image.png

-x FILE: 是否存在且可执行 
image.png

文件特殊权限测试:
-u FILE:是否存在且拥有suid权限
image.png

-g FILE:是否存在且拥有sgid权限
-k FILE:是否存在且拥有sticky权限
(3)Bash的文件属性测试
文件大小测试:

-s FILE: 是否存在且非空 
image.png

文件是否打开:
-t fd: fd表示文件描述符是否已经打开且与某终端相关
-N FILE:文件自动上一次被读取之后是否被修改过
-O FILE:当前有效用户是否为文件属主
-G FILE:当前有效用户是否为文件属组
(4)使用read命令来接受输入
使用read来把输入值分配给一个或多个shell变量
image.png
image.png
image.png

-p 指定要显示的提示 ——read -p
image.png

-s 静默输入,一般用于密码
image.png

-n N 指定输入的字符长度N
image.png

-d ‘字符’ 输入结束符
image.png

-t N TIMEOUT为N秒 read 从标准输入中读取值,给每个单词分配一个变量
所有剩余单词都被分配给最后一个变量
read -p “Enter a filename: “ FILE
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容

  • 概述 首先,咱们来了解一下,什么是Shell。操作系统内核给我们提供了各种接口,同时也提供了各种用户层的库,理论上...
    keysaim阅读 1,365评论 0 0
  • 一、命令基本格式 命令提示符 当登录linux系统时,最常见的命令就是:** [root@bogon ~]#**其...
    鲁克巴克诗阅读 860评论 0 6
  • 1. shell脚本: 包含一些命令或声明,并符合一定格式的文本文件  格式要求:首行shebang(#!)机制...
    尛尛大尹阅读 1,881评论 0 1
  • 人生的最高境界是佛为心,道为骨,儒为表,大度看世界。技在手,能在身,思在脑,从容过生活。 ...
    Maple说潮汕阅读 2,801评论 3 2
  • 沪指十字星报收,市场题材缺乏 早盘两市指数低开,沪指小幅震荡,创业板指数低开低走,但跌幅并不大,尾盘跌幅收窄,两市...
    凸逼南波万阅读 173评论 0 0