Shell脚本在我们日常的开发和学习中扮演着重要的角色。比如看一些开源项目,比如项目中的各种脚本,对于推广生产力工具很有帮助!1、命令提示1、-x命令跟踪调试执行#!/bin/shnum1=10num2=20if(($num1<=$num2));thenechonum1lesserequalnum2elseechonum1greaternum2fi执行:?notegit:(master)?sh-x/Users/fanhaodong/Desktop/project/test.sh+num1=10+num2=20+((10<=20))+echonum1lesserequalnum2num1lesserequalnum22,-ccommand(执行命令参数)?notegit:(master)?sh-c<echohelloworlddquote>echohelloworld2dquote>"heredoc>EOFhelloworldhelloworld23、使用set变量#!/bin/sh#-vPrintshellinputlinesastheyareread.#-xPrintcommandsandtheirargumentsastheyareexecuted.#-eExitimmediatelyifacommandexitswithanon-zerostatus.set-execho"helloworld"exit1执行?makefilegit:(master)?sh./main.sh+echo'helloworld'helloworld+exit1?makefilegit:(master)?echo$?1help可以看到:sh-c"helpset"2、语法提示1、${}和$适用场景1)$可能有语法歧义,所以一般使用${}#!/bin/shs="mynameiss"echooutput:$saecho输出:${s}a#Output:#Output:mynameissa2,((cmd))canreplace[-le]commandnum1=10num2=20if(($num1<=$num2));thenechonum1lesserequalnum2fi3,cat[>>|>][file]<如果重定向操作符是<<-,那么分隔符(EOF)所在行首的制表符(Tab)将被去掉。这可以解决脚本Tabs中自然缩进导致的问题。?testcat>glide.yaml<name:tomheredoc>age:10heredoc>hobby:heredoc>-footballheredoc>EOF?testcatglide.yamlname:tomage:10hobby:-football4,单引号、双引号、不引号的区别#!/bin/shname="tom"f1(){echo"f1helloworldmynameis$name"}f2(){echo'f2helloworldmynameis$name'}f3(){echof3helloworldmynameis$name}f1f2f3输出?生成文件git:(master)?sh。/main.shf1helloworldmynameistomf2helloworldmynameis$namef3helloworld./main.sh:line19:my:commandnotfound可以看到双引号会自动给变量赋值单引号不会给变量赋值等操作没有引号,函数如换行不能实现!只能使用换行符号f3(){echof3helloworld\mynameis$name}5、特殊变量$0:当前脚本的文件名$n:传递给脚本或函数的参数。n是一个数字,表示参数的数量。例如,第一个参数是$1,第二个参数是$2。$#:传递给脚本或函数的参数数量。$*:传递给脚本或函数的所有参数。$@:传递给脚本或函数的所有参数(推荐使用这个),当使用""双引号时$*将变成字符串而不是数组$?:上一个命令的退出状态,或者返回值功能。通常,大多数命令在成功执行后将返回0,如果执行失败则返回1。$$:当前shell进程ID。对于shell脚本,这是脚本所在的进程ID。6、[[]]和[]标准及基本语法规范具体规范:#!/bin/shname=""if[[-z$name]];thenecho"iszero"执行后发现的Fi7./bin/sh/bin/bash的区别/bin/sh和/bin/bash的区别3.$(cmd)获取命令结果有两种写法,一种是$(),不是所有的shell都支持,但是更直观,另一个是“``”(适用于更多平台)#!/bin/shecho`ls-a/Users/fanhaodong/note`echo$(ls-a/Users/fanhaodong/note)输出:....DS_Store1714.jpgdocker-rocketmq-clustergridea-homehexo-homenotepdfvuepress-starter....DS_Store1714.jpgdocker-rocketmq-clustergridea-homehexo-homenotepdfvuepress-starter4,输入输出重定向2>&1常用于program,standardoutput,但是还是有错误输出,所以需要合并成一个流。其实在Go程序中执行脚本时,可以指定标准输出和错误输出命令:=exec.Command(shell,"-c",cmd)command.Stdout=os.Stdoutcommand.Stderr=时os.Stderr的使用:默认是标准输出重定向,和1>2>&1一样,表示将标准错误输出重定向到标准输出。&>file表示标准输出,标准输出错误输出重定向到文件file例如:command>out.file2>&1&command>out.file将命令的标准输出重定向到out.file文件,即output内容不会打印到屏幕上,而是输出到.file文件。2>&1是将标准错误重定向到标准输出,这里标准输出已经重定向到out.file文件,即标准错误也输出到out.file文件。最后一个&是让命令在后台执行。5.if语句if其实就是测试命令1.格式1)写if[condition];then#bodyelif[condition];then#bodyelse#bodyfi2)写if[-f"/Users/fanhaodong/note/note而不是换行/Makefile1"];thenecho111;echo222;elif[-f"/Users/fanhaodong/note/note/README.md"];thenecho333;echo4444;elseecho555;echo666;fi2,结果获取/判断输出0,意味着true,你可以使用$?得到结果3.例如调试条件?notegit:(master)?test"abc"!="def"?notegit:(master)?echo$?04.测试文件是否存在如果要判断a文件是否存在,只需要-e,输出0表示文件存在(判断类型时不建议这样)如果要判断文件是否a文件夹,是否存在,只需要-d如果判断一个文件是不是普通文件,是否存在,只需要-f-L文件名如果文件名是符号链接,则为真[root@019066c0cd63~]#ls-allrwxrwxrwx1rootroot5Mar109:49c.txt->a.txt[root@019066c0cd63~]#[-L"./c.txt"][root@019066c0cd63~]#echo$?0-r文件名如果文件名可读则为真-w文件名如果文件名可写则为真-x文件名trueiffilenameisexecutable-sfilenametrueiffilelengthisnot0-hfilenametrueiffileisasoftlink?notegit:(master)?[-f"/Users/fanhaodong/note/note/Makefile"]?notegit:(master)?echo$?0?notegit:(master)?[-f"/Users/fanhaodong/note/note/Makefile1"]?notegit:(master)?echo$?15.建议加""来定义字符串操作字符串1)判断字符串是否为空-z(零)#!/bin/shstr=""if[-z"${str}"];thenechostrisemptyfi#strisempty2)判断两个字符串是否相同#!/bin/shstr1="str"str2="str2"if["$str1"="$str2"];thenechostr1isequalstr2elseechostr1isnotequalstr2fi#str1isnotequalstr24,测试命令是否存在command-v$##!/bin/shcmd=goif[`command-v$cmd`];thenecho$cmdcommandisexistselseecho$cmdcommandnotexistsfi#gocommandisexists5,获取字符串长度${#var}#!??/bin/shstr="hello"str1=helloechostrechostr1的长度为${#str}echostr1的长度为${#str1}#str长度为8#str1长度为56,数字比较-eq等于-ne不等于-gt大于-ge大于或等于-lt小于-le小于或等于#!/bin/shnum1=10num2=20if(($num1<=$num2));thenechonum1lesserequalnum2fiif[$num1-le$num2];thenechonum1lesserequalnum2fi#num1lesserequalnum2#num1lesserequalnum27,如果在shell脚本中判断'-a'-'-z'的含义6,for循环1,forin;do;;done#!/bin/bashforitemin{1..5};doecho"$item";done[Running]/bin/bash"/Users/fanhaodong/note/note/Linux/shell/file.sh"123452、for((x=0;x<10;x++));做;;donefor((x=0;x<10;x++));doecho"$x";done7,awk1,示例演示[root@19096dee708bdata]#catdemo.txt11221112233脚本[root@19096dee708bdata]#awk-F':''BEGIN{print"start"}/:/{printf"do1$1=%s$2=%s\n",$1,$2}{print"do2.."}END{print"end"}'demo.txtstartdo1$1=11$2=22do2。.do2..do1$1=22$2=33do2..end2,格式awk-arg1x1-arg2x2'BEGIN{开始执行脚本}Condition{过程1}{过程2}END{循环体执行完后最后执行}'其中conditions执行正则表达式、判断等也支持一些内置函数和一些内置变量!supportiffunction8,sedfirstgun的sed功能和mac的设置有些不同!详见:https://superuser.com/questions/307165/newlines-in-sed-on-mac-os-x专门写在其他文档中,目前使用的多条命令不共享!