当前位置: 首页 > 科技观察

这些必备的Linuxshell知识你掌握了吗

时间:2023-03-22 14:18:57 科技观察

前言在linux下使用shell编程往往可以大大简化我们的工作。而你掌握了以下所有必要的知识吗?输入参数和默认变量对于shell脚本,有些内容是专门用来处理参数的,它们都有特定的含义,例如:/home/shouwang/test.shpara1para2para3$0$1$2$3脚本名***参数号其中三个参数,$0代表执行的脚本名称,$1和$2分别代表第一个和第二个参数。此外,还有一些其他的默认变量,例如:#表示脚本后面的参数个数,在前面的例子中,有3个参数$@表示所有参数,可以遍历$*表示所有参数,如整体来说,它和$*很像,但是有区别$$代表当前脚本的进程ID$?表示上一个命令的退出状态变量给变量赋值,就用等号,但是等号两边必须不能有空格,等号右边有空格的字符串必须也用引号括起来:para1="helloworld"#字符串直接赋值给变量para1unset用于取消变量。例如:unsetpara1如何使用变量?使用变量时,需要在变量前加$,比如打印前面para1的内容:echo"para1is$para1"#会输出para1isheoworld或者在变量名两边加花括号:echo"para1是${para1}!"#will输出para1isheoworld!命令执行要在shell中执行命令,通常只需要像在终端中一样执行命令即可。但是,如果你想把命令结果打印出来,这个方法就不行了。所以shell的命令方式往往有:a=`ls`#`是左上角的~键,不是单引号也不是$,后面的括号是执行的命令:echo"currentpathis$(pwd)"#另外,前两种这种方法对于计算表达式也是行不通的,但是应该采用下面的方法:echo"1+1=$((1+1))"#print:1+1=2,即在$计算表达式换行后使用双括号。如果要执行的命令存储在变量中怎么办?前面的方法都行不通,当然括号里的内容作为命令执行还是有效的。使用下面的方法,例如:a="ls"echo"$($a)"但是如果字符串中包含多个命令,上面的方法就不可行了,应该使用下面的方法:a="ls;pwd"echo"$(eval$a)"v这使用了eval,并将a的内容作为命令执行。条件分支一般表示如果命令执行成功,其返回值为0,否则为非0。因此,可以通过以下方式判断前面命令的执行结果:if[$?-eq0]thenecho"success"elif[$?-eq1]thenecho"failed,codeis1"elseecho"othercode"ficase语句作为如下:name="aa"case$namein"aa")echo"nameis$name";;"")echo"nameisempty";;"bb")echo"nameis$name";;*)echo"othername";;esac初学者尤其需要注意以下几点:[]前面必须有空格,后面是逻辑表达式ifelif后面跟着then,Then就是要执行的语句。如果要打印上一条命令的执行结果,最好的办法是赋值$?到一个变量,因为一旦命令被执行,$?可能会改变。case***的每一个分支都以两个分号结尾,***是case倒写,即esac。如何使用多个条件,两种方法,方法一:if[10-gt5-o10-gt4];thenecho"10>5or10>4"fi方法二:if[10-gt5]||[10-gt4];thenecho"10>5or10>4"fi其中-o或||意思是或。这里还有一些常见的条件判断。总结如下:ooror,同||-a和,与&&相同!非整数判断:-eq两个数是否相等-ne两个数是否不相等-gt前者是否大于后者(大于)-lt前面是否小于后者(小于)-ge是否前者大于等于后者(大于等于)-le前者是否小于等于后者(小于等于)字符串判断str1expstr2:-z"$str1"str1是否为空字符串-n"$str1"str1是否不为空字符串"$str1"=="$str2"str1是否等于str2"$str1"!="$str2"str1是否不等于str2"$str1"=~"str2"str1是否包含str2特别注意,字符串变量***是用引号括起来的,因为一旦字符串中有空格,这个表达式就是错误的,有兴趣的可以试一下str1="helloworld"和str2="hello"对比一下。文件目录判断:filename-f$filename是一个文件-e$filename存在-d$filename是一个目录-s$filename文件存在且不为空!-s$filenamefile是空循环循环形式一,和Python的forin很像:#遍历输出脚本的参数foriin$@;doecho$idone循环形式二,很像C语言的风格:for((i=0;i<10;i++));doecho$idone循环打印0到9。循环形式三:foriin{1..5};doecho"Welcome$i"done循环打印1到5。循环方式四:while["$ans"!="yes"]doread-p"pleaseinputyestoexitloop:"ansdone只有输入yes才会退出循环。即当条件满足时,执行循环。循环方式五:ans=yesuntil[$ans!="yes"]doread-p"pleaseinputyestoexitloop:"这里的ansdone表示只有当ans不为yes时,循环才会终止。循环方式六:foriin{5..15..3};doecho"numberis$i"done每打印5次,即打印5,8,11,14。定义函数的方式如下:myfunc(){echo"helloworld$1"}或者:functionmyfunc(){echo"helloworld$1"}函数调用:para1="shouwang"myfunc$para1返回值通常为return返回值of一个函数只支持0-255,所以如果你想得到返回值,可以使用下面的方法。functionmyfunc(){localmyresult='somevalue'echo$myresult}val=$(myfunc)#val的值为somevalue,适合通过return判断函数执行是否成功:functionmyfunc(){#dosomethingreturn0}ifmyfunc;thenecho"success"elseecho"failed"ficommentshell使用#来注释一行内容,我们之前看到过:#!/bin/bash#Thisisalineofcomment:'Thisisamulti-linecomment'ls:<log.dat在这种情况下,如果命令执行过程中出现错误,错误将被打印到控制台。所以如果你在程序中调用它,它不会将错误信息保存在日志中。方法二,标准输出和标准错误都保存到日??志文件:./test.sh>log.dat2>&12>&1意思可以参考《如何理解linuxshell中的2>&1》方法三,保存日志文件的同时,也输出到控制台:./test.sh|teelog.dat脚本最常见的执行方式以前看过:./test.sh其他执行方式:shtest.sh#executeinsubprocesssh-xtest.sh#willprintand在终端执行到命令,适合调试sourcetest.sh#test.sh在父进程执行。test.sh#不需要赋予执行权限,临时执行脚本的退出代码为经常使用。很多情况下,我们需要获取脚本的执行结果,即退出状态,通常0表示执行成功,而不是0表示失败。为了得到退出代码,我们需要使用exit。示例:#!/bin/bashfunctionmyfun(){if[$#-lt2]thenecho"paranumerror"exit1fiecho"ok"exit2}if[$#-lt1]thenecho"paranumerror"exit1fireturnVal=`myfunaa`echo"endshell"exit0here一需要特别注意的是,如果你执行一个带有returnVal=`myfunaa`这样语句的函数,即使函数中有exit,也不会退出脚本执行,只是退出函数。这是因为exit是退出当前进程,这样执行函数相当于fork了一个子进程,所以不会退出当前脚本。最终结果会看到,不管你的函数参数是什么***endshell都会打印。./测试.sh;回声$?0小结以上就是shell编程最基本也是最关键的内容。当然,这还不是全部。比如数组、字典、参数处理等就不详细介绍了。限于篇幅,将在后面的文章中详细介绍。学好shell,解放双手。