10-shell编程基础 本文共有8312个字,关键词: shell编程: 语言的特征:变量、函数、流程控制、判断 编译型语言:c、c++、c#、java 解释型语言:php、python、perl、shell 程序的编程风格: 面向过程:以指令为中心,数据服务于指令 面向对象:以数据为中心,指令服务于数据 ·计算机只识别二进制指令 ·程序由指令+数据组成 ·shell程序提供了编程能力,依靠调用系统提供的命令(已有的二进制程序),组织成一定形式解释执行的。 ·编译:高级语言→编译器→目标代码(c/c++/java…) ·解释:高级语言→解释器→机器代码(shell/perl/python) ·过程式编程: 顺序执行、循环执行、选择执行 ·编程语言的基本结构: 数据存储:变量、数组 表达式 语句 ·shell编程语言除了控制保留字所写的结构外,剩余都是系统中的命令 shell是过程式的、解释执行的、严重依赖操作系统的语言 shell脚本是文本文件,但是这个文本文件是有特殊格式的 ·第一行要写清楚解释器的路径,由哪个解释器解释执行 #!/bin/bash(顶格写) ·shell脚本是由解释器解释执行的,解释器是二进制文件运行在CPU上 ·shell脚本还需要依赖PATH环境变量,如果是当前用户运行脚本,命令是可以执行的,如果是计划任务则不会登录执行,需要在脚本中定义PATH环境变量 ·内核是通过魔数(magic number)来判断文件的格式,文件前的几个字节 实例:统计/etc/passwd文件有多少行 ~]#vim /tmp/test.sh #编辑文件,不存在的文件自动创建(需保存) 按下键盘上的小写字母a,并输入如下内容 ``` #!/bin/bash #Version:0.0.1 #Author:stone #Discription:count /etc/passwd has line filename=”/etc/passwd” #定义文件路径变量,方便替换 cat $filename #查看文件内容 wc -l $filename #统计文件行数 ``` 按Esc,并且键入冒号,输入wq,回车保存文件 chmod +x /tmp/test.sh #给脚本执行权限 ./tmp/test.sh #执行脚本 变量:命令的内存空间 ·不同的数据存储的格式可能不同 字符型、数值型… ASCII 127个字符的编码集 逻辑运算符: &&与 true 0 真 || 或 false 1 假 ! 非 短路运算: 与:两个条件都为真时才成立 当第一个参数为真时,第二个参数才参与运算 当第一个参数为假时,第二个参数不参与运算 或:两个条件任意 一个为真,则结果为真 当第一个参数为真时,第二个参数不参与运算 当第一个参数为假时,第二个参数参与运算 linux上的文本处理三剑客 grep 文本过滤工具,基于模式(pattern),显示匹配的行 grep支持正则 egrep支持扩展正则 fgrep 不支持正则 sed 文本流编辑器,是一个文本编辑工具(行编辑工具) awk linux上实现的是gawk,awk是一门单独的编程语言,也就是说awk也是一个解释器,awk既不是用于编辑文本也不是用于过滤文本,而是将文本进行美观输出,所以awk是一个文本报告生成器 grep及正则表达式: 文本搜索工具,根据用户指定的模式,对目标用户文本进行匹配检查,打印匹配到的行。 模式:由正则表达式及文本字符所编写的模式,其中有些字符不表示字符字面意义,表示控制或者通配的功能 元字符:特殊功能的字符 正则表达式在编码上有所不同,所以分为两类: ·基本正则表达式BRE ·扩展正则表达式ERG ·grep默认是支持基本正则表达式的 ·扩展正则表达式需要使用egrep或者grep -E ·正则表达式引擎:进行正则表达式的解释及匹配检查 ~]#grep [option] PATTERN [FILENAME] —color=auto 对匹配到的文本着色显示 -v(小) 反向显示,显示无法被匹配到的行 -i 匹配时忽略大小写 -o 仅显匹配到的子串 -q 静默模式,不会输出任何信息 -A# 显示匹配行的后#行 after -B# 显示匹配行的前#行 before -C# 显示匹配行的前后各#行 -E 使用扩展的正则表达式 基本的正则表达式元字符: ·grep使用的模式应当使用引号包含起来 ``` "." 匹配任意单个字符 ”[ ]” 匹配指定范围内的任意单个字符 ”[^]” 匹配指定范围外的任意单个字符 "[:digit:]" 所有数字0-9 ”[:lower:]” 所有的小写字母 ”[:uppper:]” 所有大写字母 ”[:alpha:]” 所有的大小写字母 ”[:alnum:]” 所有的字母和数字 ”[:punct:]” 所有特殊字符 ”[:space:]” 空格字符 ·次数匹配,用在要指定出现次数的字符后面 ”“ 匹配前面的字符任意次,““本身仅表示次数 ”.*” 任意长度的任意字符 ”\?” 匹配前面的字符0次或一次,即前面的字符可有可无。 ”+“ 匹配前面的字符至少一次 ”{m,n}“ 匹配其前的字符至少m次,至多n次 ”{m}“ 匹配其前面的字符m次 ”{0,n}“ 匹配前面的字符至多n次 ”{m,}“ 匹配其前的字符至少m次 ``` ·位置锚定 ``` ”^” 行首锚定,使用在最左侧 ”$” 行尾锚定,使用在最右侧 ”^PATTERN$” 用模式匹配整行,匹配到为真,否则为假 ”^$” 空行,none ”^[[:space:]]*” 空白行,没有可见字符的行 ”\<” 词首锚定,用于单词的左侧 ”\b” 词首锚定,用于单词的左侧 ”\>” 词尾锚定,用于单词的右侧 ”\b” 词尾锚定,用于单词的右侧 ”\” 单词锚定 ”\bPATTERN\b” 单词锚定 ·分组:“()“,小括号在shell中有特殊含义,所以需要转义 将一段字符当作一个整体处理 字符一旦分组以后,在所在的正则表达式中还有第二个作用:后向引用 ·后向引用:引用前面分组括号中模式所匹配到的字符 一旦一个模式能够匹配到一个字符串,在后面的任何位置我么都可以再次引用这个模式匹配到的字符 分组中的模式匹配到的内容会被正则表达式引擎记录于内部变量中,这些变量的命名方式为\1,\2,\3等等 \1表示从左起第一个括号到与之匹配的括号之间模式所匹配到的字符 分组允许嵌套,最里面的一对括号为最后一个分组。 ·后向引用,引用的是分组括号中模式所匹配到的字符,而非模式本身 ``` egrep及其扩展的正则表达式: egrep相当于grep -E ·扩展正则表达式的原字符 ·字符匹配: “.” 任意单个字符 “[]” 指定范围的单个字符 “[^]” 指定范围外的单个字符 ·次数匹配 “*” 匹配其前的字符任意次 “?” 匹配其前的字符0或1 "+" 匹配其前的字符至少一次 "{m}" 匹配其前的字符m次 "{0,n}" 匹配其前的字符至多n次 "{m,}" 匹配其前的字符至少m次 "{m,n}" 匹配其前的字符至少m次 •锚定字符 "^" 行首 "$" 行尾 "\<" "\b" 锚定词首 "\>" "\b" 锚定词尾 •分组 "()" 将扩展正则表达式的一部分当做一个整体 后向引用:\1,\2,\3...... •或者 a|b a或者b C|cat C或者cat (C|c)at Cat或者cat ~]#basename /etc/passwd #取路径的基名passwd ~]#dirname /etc/passwd #取目录名/etc bash中算术运算的实现: •let sum=$num1+$num2 #计算num1+num2的和保存在sum变量中 •var=$[算数表达式] #有返回值,可以直接调用 •var=$((算数表达式)) #也可实现直接引用 •var=$(expr arg1 arg2 arg3....) #arg1、arg3操作数,arg2为操作符 #使用expr需要注意,*号需要转义,此处为命令行的调用,会被当做通配符 增强型赋值: +=、-=、*=、%=、/= let count+=1 let count=$count+1 let var++ #自加 let var-- #自减 •bash内建的随机数生成器$RANDOM $RANDOM是bash的内建变量,(0-65535) 列如我们要在1-60中生成一个随机数 echo $[$RANDOM%60+1] #+1是因为$RANDOM%60的随机范围为[0-59] 条件测试: 判断某需求是否满足,需要由测试机制来实现,专用的测试表达式需要由测试命令辅助完成测试过程 •测试命令: ~]#test expression(表达式) ~]#[ expression ] #一对中括号为测试命令,同test ~]#[[ expression ]] #两对中括号中为bash中的关键字 #expression与中括号之间要有空格,否则会报错 •bash中的测试类型: 数值测试(数值大小) 字符测试(字符串大小) 文件测试(文件存在与否,读写执行等权限) •数值测试:一般不加引号,加引号就是字符串了 -gt 左侧(数值)是否大于右侧(数值) -ge 左侧是否大于等于右侧 -eq 左侧是否等于右侧 -ne 左侧是否不等于右侧 -lt 左侧是否小于右侧 -le 左侧是否小于等于右侧 •字符串测试: ==/= 等值测试,一个或两个等于号都可以,但是为了与赋值区分,监视使用前者 ">" 是否大于 "<" 是否小于 "!=" 是否不等于 [[ "char" =~ "RATTER" ]] #左侧的字符串是否能被右侧的模式匹配到 [ -z "string" ] #测试字符串是否为空,空位真。 [ -n "string" ] #测试字符串是否不空,不空为真 字符串要加引号,使用单引号还是双引号取决于是否要做变量替换 •文件测试 ~]#man bash #查看bash的各种特性 -e filename 文件存在为真,否则为假 -b filename 文件存在且为block设备文件,否则为假 -c filename 文件存在且为字符设备文件,否则为假 -d filename 存在且为目录文件,否则为假 -f filename 存在且为文件,否则为假 -S filename 存在且为套接字文件,否则为假 -L filename 存在且为符号链接文件,否则为假 -p filename 存在且为命名的管道文件,否则为假,我们使用的为匿名管道"|" •文件权限测试 -r filename 是否存在且可读取 -w filename 是否存在且可写 -x filename 是否存在且可执行 •文件的特殊权限 -g filename 是否存在且拥有sgid权限 -u filename 是否存在且拥有suid权限 -k filename 是否存在且拥有sbit(sticky)权限 •文件大小测试 -s filename 文件是否存在且为空 •文件打开性测试 -t fd fd为文件描述符,是否已打开且与某终端相关 -N filename 文件自上一次读取后是否修改过 -G filename 当前有效用户是否为文件属组 -O filename 当前有效用户是否为当前属主 •双目测试 file1 -ef file2 file1和file2是否为指向同一个设备上相同的inode(是否为硬链接) file1 -nt file2 file1是否新于file2,nt为new than file1 -ot file2 file1是否旧于file2,ot为old than #常用于备份中的判断,如果新于备份文件则备份 •组合测试条件 •逻辑运算 && 与 COMMAND1 && COMMAND2 || 或 COMMAND1 && COMMAND2 ! 非 !COMMAND eg: [ -e file ] && [ -r file ] #文件是否存在且可读 -a 与 expression -a expression -o 或 expression -o expression ! 非 !expression eg: [ -e file -a -r file ] #文件是否存在且可读 •摩根定律:整体取反后内部符号要取反 [ ! -r file /tmp/test ] && [ ! -w /tmp/test ] 相当于 [ ! \( -r /tmp/test -o -w /tmp/test \) ] shell脚本编程,过程式编程 1. 顺序执行,无需控制 2. 选择执行,需要使用关键字来实现 3. 循环执行 •选择执行 if单分支语句 if 条件判断; then 条件为真时的代码 fi if双分支语句 if 条件判断; then 条件为真执行的语句 else 条件为假时执行的语句 fi if多分支语句 if 条件判断;then 条件为真执行的语句 else 条件为假时执行的语句 fi •if语句逐条进行判断,第一次遇到"真"条件时,执行其分支,而后结束 •if语句允许嵌套 条件判断就是命令,自身为表达式的需要转为测试语句 循环:for、while、until 循环体:要执行的代码,可能执行N次 进入条件 退出条件 for 变量名 in 列表; do 循环体 done while 条件;do #当条件成立时,循环体一直执行,不成立则结束 循环体 done until 条件;do #当条件不成立时,循环体一直执行,条件成立则结束寻循环 循环体 done while :;do #无限循环 循环体 done •一般来说循环体会调用变量名,执行的机制为: 依次将列表中的元素赋值给"变量名",每次赋值执行一次循环体,直到列表的元素耗尽,循环结束,列表是一次性生成存放在内存中的。 列表的生成方式: 直接给出列表 整数列表 {StartNumber..StopNumber} seq 起始数 增量 结束数 seq [start [step]] stop 可使用能返回列表的命令 glob文件名通配 函数 function 函数名() { 函数体 } #调用函数时直接使用函数名即可 bash脚本常使用的命令 read 该命令能完成和用户的交互,能够实现多个变量对应存储 -p "提示信息" #打印提示信息 -t NUM #指定超时时间,为空(用户不输入)时应设定默认值 •如果用户输入的参数超过设定变量的数量,则最后一个变量接收余下的所有参数,如果变量足够则参数对应存储 ~]#bash -n *.sh #检查脚本是否存在语法错误 ~]#bash -x *.bash #显示每一行代码的执行结果,调试执行 ~]#echo [option] "...." #打印字符串至屏幕 -e 支持反斜线的换行符、控制符 \n 换行 \t 制表符 -n 取消输出行尾的换行符的换行符,即不换行输出。 -e 支持颜色输 开始:\e [字体颜色;字体底色m \033[字体颜色;字体底色m 结束:\e[0m \033[0m #0m为结束所有的格式 •脚本的命名一般为*.sh •脚本的执行方式: 添加x执行权限,使用绝对路径或相对路径 使用bash命令,调用脚本,即让解析器主动去读取脚本 ~]#bash -n *.sh #检查脚本的语法错误 ~]#bash -x *.sh #显示脚本的执行过程 •命令执行的优先级: 1. 使用绝对路径或相对路径 2. 别名命名的命令 3. bash内置的命令 4. 根据环境变量定义的目录查找到的命令 管道符和xargs命令的区别: ~]#echo "--help" |cat #执行该命令的结果为"--help" ~]#echo "--help" |xargs cat #执行该命令的结果为cat的帮助 shell脚本中的特殊符号: 单引号:强引用,单引号中的符号,如"$"、"反引号"等都没有特殊意义 •Tips:PS1变量的复制使用的是单引号 双引号:弱引用,在双引号的引用下,特殊符号几乎没有特殊意义 $ 变量引用 `` 命令的调用 「一键投喂 软糖/蛋糕/布丁/牛奶/冰阔乐!」 赞赏 × 几人行 (๑>ڡ<)☆谢谢老板~ 2元 5元 10元 50元 100元 任意金额 2元 使用微信扫描二维码完成支付 版权声明:本文为作者原创,如需转载须联系作者本人同意,未经作者本人同意不得擅自转载。 基础笔记综合整理 2018-10-06 评论 1753 次浏览