Shell脚本学习(基础)前言:计划本系列shell脚本学习分两部分,第一部分为shell脚本基础篇,第二部分是进阶篇。本册为基础篇,有几个截图有个错误,是#!/bin/bash,不是#/bin/bash,还请多包含。基础篇目录:一.shell必知............................................................2二.shell基础............................................................41.数学运算............................................................42.结构化............................................................53.循环............................................................74.优先级............................................................85.函数............................................................116.awk和sed............................................................14一.Shell脚本必知1)反引号``:将shell命令的输出赋给变量2)重定向:将输出倒入到某文件内,重新改变了文件将文件内容定向到输入只是在文件末尾附加&错误和正确信息一起输出到文件3)管道:|不必多说,非常重要4)Test命令:判断如果符合返回0,则$?=0数值比较:字符串比较:文件比较:n1-eqn2n1=n2n1-nen2n1!=n2n1-gtn2n1n2n1-gen2n1=n2n1-ltn2n1n2n1-len2n1=n2str1=str2str1!=str2str1\str2str1\str2-nstr1Str1’slengthnotequal0-zstr1Str1’slengthequal0-dfilefile是不是存在且是个目录-efilefile是不是存在-ffilefile是不是存在并且是个文件-rfilefile是不是存在并且可读-sfilefile是不是存在并且非空-wfilefile是不是存在且可写-xfilefile是不是存在且可执行-Ofilefile是不是存在且属于当前用户所有-Gfilefile是不是存在且默认组和当前用户相同File1-ntfile2File1是不是比file2新File1-otfile2File1是不是比file2旧5)脚本参数$0脚本名字$1..$9脚本第1个..第9个参数${10}..脚本第10个参数以后需加大括号$#脚本运行时就有的命令行参数个数${!#}最后一个参数值,无参数时候返回脚本名没成功?$*显示所有参数,所有参数合成以单个单词形式保存$@显示所有参数,所有参数分开保存,能用for遍历二.Shell脚本基础1)数学运算A.expr命令例子:expr1+5————》6注意:1+5必须有空格隔开。expr命令也支持+-*/%length等运算(*必须加转义\*)B.$[operation]例子:echo$[1+5]--------------6注意:1+5必须有空格隔开加,减,乘,除,取余,或,与,大小等于均支持。注意:bashshell只支持整数运算,浮点数运算用zshell你也可以用bc进行嵌入到shell脚本中。例子:echoscale=4;6.0/5|bc---------》1.2000Scale是设定有几位小数。格式echo“scale=X,expression”|bc2)结构化语句Aif-then-elif-then-else-ifIf后的命令执行结果返回0,执行then格式:ifcommandthenCommand集合elifcommandthenCommand集合elseCommand集合fi例子:Bcase语句格式:caseXinpattern1|pattern2)commands1;;pattern3)commands2;;*)commands3;;esacCif的高级特性1)双圆括号(()):针对test命令数值比较的扩展Val++val--++val--val**(幂运算)&&||例如:if((5**220))2)双方括号[[]]:针对test命令字符串比较的扩展可以定义正则表达式例如:if[[‘aa’==a*]]3)循环结构Afor--do--done例子:1.fortestinapplebananacatdogdoecho$testdone2.fortestin`catdemo1.sh`doecho$testdone3.for((test=0;test=4;test++))doecho$testdoneBwhile命令格式:whiletestcommanddoothercommandsdone例子:Cbreak命令和continue命令3)处理用户输入A基本读取read命令接受从标准输入或另一文件描述符的输入。例子:readnameread-p“hello”name-p可以指定提示符read-p“hello”read命令无变量时候将输入保存在$REPLY内。read-t5-phelloname-t指定了没有输入的情况下多少秒后关闭,如果没有输入,会返回一个非0状态。Read-s-p“passwd:”passwd-s当输入时候i不会显示在屏幕上。catdemo1.sh|whilereadline从文件中每次抓取一句话。B重定向文件描述符:所以/标准输入输出1将正确结果重定向2将错误结果重定向&将错误结果正确结果一起重定向临时重定向数字前加&例如&2,错误信息随机地方out永久重定向exec命令例如:exec1testoutecho“sad”0标准输入1标准输出2标准错误该脚本的所有输出都定向到testout文件内。关闭文件重定向符&-例如exec3&-,脚本中关闭描述符3,脚本中使用会出错C消息记录tee命令格式:teefilename命令tee可以将STDIN的内容既发送到STDOUT内,又发送到指定文件。4)调度作业优先级和自动任务注意,linux系统作业优先级由高向低为-20到+20,脚本优先级别默认分配为0Anice命令:可以调整(准备启动的)作业优先级,格式:nice-n级别filenameBrenice命令:调整(已经启动的)作业优先级,格式:renice级别-pfilePID两个命令的限制:C定时任务crontab普通用户只能修改自己的进程普通用户只能降低自己作业的优先级Root用户随意crontab-e//编辑crontab-l//显示*****command分钟,*表示每分钟,不同时间,隔开小时。不同时间,隔开,相连时间用-连日。不同时间,隔开,相连时间用-连月。不同时间,隔开,相连时间用-连星期。不同时间,隔开,相连时间用-连命令5)函数A函数声明格式1:functionname{commands}使用:直接name注意函数使用前必须声明,而且函数名必须唯一,否则会覆盖前一个。B返回值(退出状态码)1)默认退出状态码即是函数最后一个命令返回的退出状态码2)return返回值returnXX值必须立即使用X值必须在0~255之间3)使用函数输出C函数传参/全局变量/局部变量函数传参:函数可以在被调用的时候给予参数,和脚本的传参一样,$1..$9等等都一模一样,需要区别的就是,函数的参数$1..$9不同于脚本本身的参数,例如:脚本第一个参数是1,但却不能直接当作函数的第一个参数,因为两者采用不同的环境变量。正常例子:全局变量:shell脚本中任何地方都有效的变量。默认情况下在脚本任何地方的地方创建的变量直接是全局变量,局部变量:默认情况下函数内部的声明的变量加上local声明时变成局部变量。例子1:任何地方的变量即是全局变量例子2:函数声明局部变量D递归E建立库不同脚本使用同样的一段代码时候,可以创建库,变得轻松例子:使用函数库的关键在source,source会在当前的shell上下文中执行命令,而不是创建一个新的shell。source./funcs=../funcs6)sed和awk处理文本和正则Ased流编辑器-escript处理多条命令,例如:sed-e‘%s/dog/cat/g;s/a/b’data1-ffile处理文件内的命令,例如:sed-fscriptdata2-n不为每个命令生成输出-i输出保存1.替换指定词组sg全文p打印此行,和sed-n连用wfile将结果写入file文件内数字替换每行第几处的词组$表示最后,例如sed‘$s/cat/dog’file^表示开头,例如sed‘^s/cat/dog’file例子1:修改全文我-小名例子2:修改指定行2-4行的我-小名例子3:光打印修改的行例子4:修改最后一行:例子5:以!形式修改路径:2.附加到指定语句之前i例子1:附加指定语句到第一行之前3.附加到指定语句之后a例子1:附加指定语句到最后一行之后4.删除指定行d注意:如果d前不加数字表示删除所有行例子1:5.改变指定句子c例子1:注意:替换s是/或者!附加ia修改行c都是\,表示换行。Bgawk命令-F指定分隔符,默认‘’-ffile读取指定程序的文件名1.awk'{printhelloworld}'aaa//对每个输入行打印helloworld,有几行打印几个2.awk'{print}'aaa//打印aaa的内容$0:所有列$1:第一列$n:第n列3.awk‘{print$1}’filename//打印第一列4.-F指定域分隔符awk-F“:”‘{print$1}’filename例子:5.awk-F':''BEGIN{printname,shell}{print$1,$7}END{printblue,/bin/nosh}//流程:每行,先执行BEGIN再执行中间的一行,最后执行END6.ARGC命令行参数个数ARGV命令行参数排列ENVIRON支持队列中系统环境变量的使用FILENAMEawk浏览的文件名FNR浏览文件的记录数FS设置输入域分隔符,等价于命令行-F选项NF浏览记录的域的个数NR已读的记录数OFS输出域分隔符ORS输出记录分隔符RS控制记录分隔符例:#awk-F':''{printfilename:FILENAME,linenumber:NR,columns:NF,linecontent:$0}'/etc/passwdfilename:/etc/passwd,linenumber:1,columns:7,linecontent:root:x:0:0:root:/root:/bin/bash7.使用printf替代print,可以让代码更加简洁,易读awk-F':''{printf(filename:%10s,linenumber:%s,columns:%s,linecontent:%s\n,FILENAME,NR,NF,$0)}'/etc/passwd8.Awk可以自己设置变量awk'BEGIN{count=0;}{count=count+1;print$0}END{printcount=,count}'aaals-l|awk'BEGIN{size=0}{size=size+$5}END{printsize=,size}'例子:9.awk能用C知识if(expression){statement;}else{statement2;}例1:统计某个文件夹下的文件占用的字节数,过滤4096大小的文件(一般都是文件夹):ls