第二部分:shell脚本编程
1.bash变量类别:(1)用户变量:分为全局变量(默认)和局部变量(需使用local限定词)。作用范围仅限于当前源程序文件,仅对于当前shell进程有效且对当前shell的子shell也无效(bash:在当前shell启动子进程;exit:退出子进程;pstree查看进程树)(2)环境变量:在程序运行时需要设置(3)位置变量:在对参数判断和命令退回值判断时使用 (4) 特殊变量2.bash变量的声明(可声不声)和赋值(若复制内容有空格需加引号):declear: -i:声明为整型 -a:声明为数组 -r:声明变量为只读3.ash的引号:引用
1.单引号:强引用 2.双引用:弱引用 3.反引用:命令替换4.引用变量值:
$varname或${varname}5.撤销变量(释放变量空间)(一般不使用):unset varname只读变量:不能撤销变量readonly xxx=xxx6.shell的特殊字符:这些字符本身有特殊意义,若要打印显示字符表面本身,需使用\转意。常见特殊字符:#:shell脚本中的注释~:主目录,相当于$HOME,例:cd ~`:命令替换符,例:`pwd`,退回命令执行的结果$:变量表达式符号&:让命令在后台运行(此符号紧加在命令后面)*:字符串通配符(:启动子shell):停止子shell\:转意字符|:管道; :命令分隔符' :强引用
" :弱引用< :输入重定向> :输出重定向/ :路径名目录分隔符? :单个任意字符! :管道行逻辑NOT[ ]:开始和结束字符集通配符{ }:开始和结束命令块注:大括号操作符{...}允许我们使用shell字符串操作的更多高级功能,即字符串处理运算符(1)字符串的变量替换运算符:
${varname:-word} //用途:如果变量未定义,则返回默认值。varname存在且非null,返回varname否word${varname:=word} //用途:如果变量未定义,则设置变量为word。varname存在且非null,返回varname否将其置为word并退回其值${varname:+word} //用途:用于测试变量存在。varname存在且非null,返回word否null${varname:?message} //用途:用于捕捉由于变量未定义而导致的错误。varname存在且非null,返回varname否打印message并退出当前脚本//每个变量都是可选,若省略冒号,则每个定义的“存在且非”改为“存在”,即变量运算符只判断变量是否存在。
(2)字符串模式匹配运算符:${varname#pattern} //如果 模式 匹配 变量取值的开头处,则删除匹配的最短部分并退回剩下部分${varname##pattern}//如果 模式 匹配 变量取值的开头处,则删除匹配的最长部分并退回剩下部分${varname%pattern}//如果 模式 匹配 变量取值的结尾处,则删除匹配的最短部分并退回剩下部分${varname%%pattern}//如果 模式 匹配 变量取值的结尾处,则删除匹配的最长部分并退回剩下部分${varname/pattern/string}${varname//pattern/string}//将varname中匹配模式的最长部分替换为string。第一种格式中,只有匹配的第一部分被替换;第二种格式中,所有匹配的部分都被替换。如果模式以#开头,则必须匹配varname的开头。如果模式以%开头,则必须匹配varname的结尾。若果string为空,匹配部分被删除。如果varname为@或*,操作被依次应用于每个位置参数,并且扩展为结果列表例;假设path的值为/home/prince/desktop/long.file.name
范例1:若${path#/*/},则为prince/desktop/long.file.name范例2:若${path##/*/},则为long.file.name范例3:若${path%.*}, 则为/home/prince/desktop/long.file范例4:若${path%%.*}, 则为/home/prince/desktop/long范例5:若${path/prince/ollir},则为/home/ollir/desktop/long.file.name7.位置参数(0-9)可直接引用,即$0-$9,但超过这个范围必须用括号括起来,如${10}常见位置变量:$0:表示脚本自己,即脚本名字$?:前一个命令运行退回值,0表示命令运行成功,非0表示失败$#:命令变量的个数$*:命令的所有变量参数8.函数(1)函数使用规则1)函数必须先定义后使用2)函数中使用exit命令退出脚本,return命令退回到原本调用函数的地方3)使用export -f 可以将函数导出到子shell中4)使用soure或dot命令可以将保存在其他文件中的函数装入当前脚本5)使用declare -f 可以找到登录会话中定义的函数。declare -F 可以查看函数名6)若要系统启动时自动加载函数,则source $HOME/.profile。注:该函数已经写入例如:$HOME/.profile的文件中(2)定义函数格式:2.1)function funcname (){ shell commands}2.2)funcname (){ shell commands}(3)删除定义的函数unset -f funcname//-f参数提示unset命令删除的是函数9.逻辑操作:(1)NOT(!):用惊叹号取反,判断条件失败时进行某些操作(2)AND(&&):连接多个conditions条件进行判断测试(真真为真)(3)OR(||):只要两个或多个条件中有一个成功,则整个判断成功10.条件控制与流程控制(1)if/else语句if/else是shell内置,用于判断当某条件成立时,则执行某些命令,常见于选择项不多的情况。使用if/else条件测试情况:1)shell变量的值2)文件字符特性3)命令运行结果(2)if/else格式:if condition
then statements elif condition then statements... else conditionthen statements... if(3)if语句中test条件测试运用:test expression=[ expression ]=` expression `3.1)test整数测试符: -eq:等于 -gt:大于 -lt:小于 -ne:不等于 -le:小于等于 -ge:大于等于3.2)test字符串测试符: 3.2.1)双目操作符: == 两字符相同 != 两字符不相同 > >= < <=3.2.2)单目操作符:-z $var 字符空为真,不空为假-n $var 字符空为假,不空为真 3.3)test文件属性测试(多为单目):-f 判断是否为普通文件-d 判断是否为目录-l 判断是否为链接-e /path/to/somewhere 判断文件是否存在-r 判断对当前用户是否有读权限-w 判断对当前用户是否有写权限-x 判断对当前用户是否有执行权限-b file为块设备文件-c file为字符设备文件-p file为管道-O 你是file的所有者-G file的组ID匹配你的IDfile1 -nt file2 file1比file2新file1 -ot file2 file1比file2旧3.4)组合条件:!:取反-a:连接两个条件取与操作(与条件)-o:连接两个条件取或操作(或条件)例:[-e /tmp/mytest] || mkdir /tmp/mytest 即:[! -e /tmp/mytest] && mkdir /tmp/mytest[-e /tmp/mytest -a -d /tmp/mytest ] || cd /tmp/mytest 即[-e /tmp/mytest ] && [-d /tmp/mytest] || cd /tmp/mytest[-e /etc/init.d/functions] && source /etc/init.d/functions[-x /etc/init.d/network ] && /etc/init.d/network start(4)case语句case也是一个流程控制结构,它可以用更精细的方式表达if-elif类型的语句1)语法格式:case expression in pattern1) statements;; pattern2) statements;; pattern3 | pattern4) statements;; ...esac//pattern之间都可以由管道字符(|)分割的几个模式组成。在这样的情况下,如果expression匹配其中任意一个模式,其相应的语句即被执行。模式匹配按照顺序依次执行,直到匹配上为止。如果都不匹配,则不执行任何操作。11.循环控制:(1)for循环用于遍历整个对象、数字列表,依次执行每个独立对象、数字的循环内容,对象可以是命令行参数、文件名、任何可以以列表格式建立的东西1.1)for循环格式:for name [in list] //遍历list中的所有对象do ...done//list为名称列表,我们在for循环中对名称列表中的每个对象进行相应操作。可以通过命令/模式匹配等操作来获取名称列表,例1:for file in `find . -iname "*.mp3"` do mpg123 $filedone例2:for file in *.mp3do mpg123 $filedone//mpg123是命令行程序,播放mp3文件。这两个例子都可以遍历mp3文件,并依次播放,但例1是遍历当前目录中的所有mp3文件,例2是仅仅遍历当前目录下的所有mp3文件。使用find命令会层层深入文件夹,依次查找,而直接列出只会包含当前目录的文件夹1.2)如果省略in list , 则默认为in "$@",即命令行参数的引用列表for name //循环命令行参数do case $name in -f) ... //进行-f参数相关的操作 -d) ... //进行-d参数相关的操作 esacdone(2)while/until循环允许代码段在某些条件为真或直到其为真时重复运行2.1)while语法格式:while conditiondo statementsdoneuntil语法格式:
until conditiondo statementsdone//while与until语句唯一不同之处在于如何判断condition的退出状态,当condition的退出状态为真时,while语句循环继续运行,until语句循环退出。//condition可以是简单的命令/列表,或者是包含&&或||连接的命令。和if语句中的test一样。 2.2)例:path=$PATH: \\当$PATH复制到一个参数path中,并在末尾加冒号while [ -n $path ];\\当path不为空时 do ls -ld ${path%%:*} \\ls -ld列出显示path中的第一个目录 path=${pat#*:} \\截去path中的第一个目录和冒号, 当path被截成空字符串("")时,退出循环done2.3)跳出循环break和continue语句允许对循环的运行精确控制,当循环体的嵌套次数超过1层时,可以传递给break或continue参数,来控制它们跳出循环或重新执行循环。注:continu用于在循环中提早开始下一轮循环,即达到循环体一次全部运行完之前。2.3.1)语法格式:while condition1 \\第一个循环体do ... while conditon2 \\第二个循环体 do ... break 2/continue 2 \\跳出或继续2层循环 donedone... \\break跳到此处继续执2.3.2)例子:
path=$PATH
while true
do if [ -z $path ] then break \\如果path为空(""),则退出循环 fi ls -ld ${path%%:*} path=${path#*:}done\\while true 是一种惯用用法,用于创造一个无限循环,永远执行(与until false语句功能相同)脚本案例:1.变量及LAMP导航菜单编写案例#!/bin/bash#by authors yhx 2016.8.11echo -e "\033[32mplease select menu follow:\033[1m" echo "1)安装apache服务器"echo "2)安装mysql服务器"echo "3)安装php服务器"echo "4)配置LAMP WEB架构"echo "...................................."2.IF条件语句各种案例演练#!/bin/bash#by authors yhx 2016.8score=$1if [ -z $score ]; then echo "usage: {$0 60|80.}"fiif [[ $score -gt 85 ]] then echo "very good"elif [[ $score -gt 75 ]] then echo "good"elif [[ $score -gt 60 ]] then echo "pass!"else echo "no pass!"fixxxxxxxxxxxxxxxx更多内容将进一步更新,敬请期待xxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
由于小菜目前能力有限,以上内容可能有所差错,还望各大神能多多赐教,感谢!!!