shell 编程 学习笔记
2012-01-04 21:45
351 查看
一、 变量
1, 用的时候可以写为$var或者${var},但当变量后有字母或者其他字符时必须用后者。
2, 用printf打印时变量最好用””,如printf “%s\n” “$var”
3, 取消变量,var= 或者unset var(先尝试取消变量否则就取消函数,-f代表函数,-v代表变量,如unset –f fn)
4, 在双引号中,可以替换变量、替换命令执行结果、替换算术运算结果。若在双引号中用\可抑制变量的替换。
5, 变量的作用范围:仅限于当前的shell,但环境变量可以在任何shell环境中有效。在执行sh文件时会另开一个shell环境,从当前环境中继承环境变量。要想在当前shell中运行必须用. cd.sh或者sourec cd.sh。
6, 环境变量:要把一个变量变成环境变量要用export,如export var =”hello”或者export var.
执行export或者export -p会列出目前的环境变量。declare –x var一样可以设为环境变量。
7, BASH内置的环境变量:
BASH:bash完整的变量名,如/bin/bash 或者 /usr/local/bin/bash
BASH_EVN:执行shell script时若此变量不为空则首先执行它。
BASH_VERSION:bash的版本
CAPATH:cd命令搜索的路径(类似在环境变量中搜索命令)
EVN:以互动模式调用sh或者在POSIX模式下时,首先检查此变量,有则首先执行它
EUID:有效的uid
FCEDITOR:fc命令默认使用的比较器
FIGNORE:在进行文件名自动 补齐时,忽略的扩展名列表。用:隔开,如”.o:~:.txt”
FUNCNAME:函数执行时的函数名(类似于php中的魔术变量__FUNCTION__)
GLOBIGNORE:做样式比较时忽略的文件名列表,用:隔开
GROUPS:数组变量,包含用户所属的组群列表
HISTCMD:当前指令执行完后它在历史指令中的排列编号,
HISTCONTROL:控制指令是否存入历史脚本文件中
ignorespace:排除开头有空格的指令
ignoredups:连续重复的指令只存一个
ignoreboth:结合前两者的功能
HISTFILE:设定历史脚本文件的路径文件名,通常是~/.bash_history
HISTFILESIZE:历史脚本文件存储指令的最大行数,默认500
HISTIGNORE:不存入历史的指令,以:隔开,如ls:ps:cd:t*:\&(&代表最后一个历史指令,若一直健入重复的指令只存入一个,&又是后台执行符号,需要用\转义)
HISTSIZE:在互动模式中shell记住的历史指令数目,默认500
HOME:当前用户的家目录
HOSTFILE:包含自动补齐主机名的数据文件,须和/etc/hosts格式相同
HOSTNAME:主机名称
HOSTTYPE:主机形态,如i386
IFS:定义字段分隔符,默认为:空格、tag字符、换行字符。
IGNOREEOF:在按Ctrl+D时,出现几次EOF才能注销系统。
INPUTRC:设定命令行函数库readline的启动配置文件,可覆盖~/.inputrc
LANG:目前语系的名称
LC_ALL:目前的locale,可覆盖LAND和LC_*的设定
LC_COLLATE:locale字母排序
LC_CTYPE:locale字符分类
LC_MESSAGES:locale信息显示的转换,如
LINENO:script脚本已执行到的行数
MACHTYPE:描述主机型态的GUN格式,如i386-pc-linux-gun
MAIL:邮件文件的名称
MAILCHECK:每隔多久检查一下邮件,默认是60秒
MAILPATH:设定检查新邮件的文件名,多个用:隔开
OLDPATH:前一个工作目录(有点类似于cd -)
OPTARG:使用getopts处理选项时,取得的选项的参数
OPTERR:若此值为1,当getopts发生错误时,不管选项行第一个字符是否为:,都显示错误信息
OSTYPE:操作系统,如linux-gun
PATH:命令搜索的路径,多个用:隔开
PPID:父进程编号
PROMPT_COMMAND:出现在主要提示符$PS1之前执行的命令
PS1:默认为\s-\v\$ <主要提示符代码见背部>
PS2:次提示符号,默认为>
PS3:select选单的提示符,默认为#?
PS4:追踪程序时各行的提示符样式,默认为+,
PWD:当前的工作目录
RANDOM:产生随机数(需要随机种子)
REPLY:在select和read没有设定读取的变量时,默认的变量名称
SECONDS:目前的shell script已执行的时间(以秒为单位)
SHELL:shell的文件路径,默认为”/bin/bash”
SHELLOPTS:经set –o指令开启的shell选项,以:分隔
SHLVL:子shell的层级数
TIMEFORMAT:设定time统计运行时间的格式《更详细的见背后》
TMOUT:shell脚本执行的超时时限
UID:用户ID
$1~$n:位置参数,传入脚本或者函数的参数,第一个参数是$1,第二个是$2,依次类推,第10个是${10},$0表示执行程序的名称
$*:代表所有位置的参数,为一字符串,如”ABC 123 XYZ”
$@:所有位置的参数组成的串行,如”ABC”、”123”、”XYZ”
$#:位置参数的个数
$?:上一个命令执行结束后的传回值,0代表执行成功,非0代表失败
$$:目前shell script的进程编号
$!:上一个后台程序的进程编号
$_:1,script执行时为bash的绝对路径,如/bin/bash。2,上一个命令执行时最后一个位置参数。3,检查邮件时,为邮件文件名。
8, 设变量为只读变量
readonly var设定var变量为只读,执行readonly或者readonly –p列出所有的只读变量。
readonly –f 函数名:设定函数只读,不可修改。
readonly –a 数组名:设定数组只读,不可修改。
或者declare –r var设定var只读
9, declare 用法:
10, 自定义环境
大多数主机在开设帐号后会自动在主目录下建立.bash_profile和.bashrc这两个文件,至于.bash_logout一般默认没有,需要自己建立。一般在.bash_profile中设定全局适用的命令、搜寻路径和环境变量,而其他大部分设定在.bashrc里,所以.bash_profile比较小,而.bashrc比较大。
而系统管理员还要维护另外三个配置文件:
/etc/profile
/etc/bash.bashrc
/etc/skel目录下所有的文件
其中/etc/profile和/etc/bash.bashrc的设定会影响所有的账号使用。在/etc/profile中设定的有umask、PATH、多国语言环境、提示符号、别名等。/etc/bash.bashrc的内容大外如下:[ -f /etc/profile ] && . /etc/profile 表示当执行交互式的shell时会检查/etc/profile是否存在,若存在就执行。
/etc/skel的作用是:当管理员开设新账号时,这个目录下的所有的文件会拷一份到新账号home目录下,作为用户的环境文件。其中包括 .bash_profile和.bashrc文件。
11,数组:第一个元素由0开始,并且如1+2这样的算术表达式也可以作为索引,${arr[5]}.
建立数组时可以指定个别元素的索引,如arr=([3]=77 [5]=100 55)第4个元素为77,第6个元素为100第7全元素为55.
$(arr[@])一次取出数组的全部元素,得到以空白隔开的全部元素,如77 100 55
$(arr[*])一次取出数组的全部元素,得到一个字符串,如”77 100 55”
$(#arr[@])或者 $(#arr[*])取得数组元素的个数
unset arr取消数组
unset arr[4]取消数组的一个元素
11, Here Document:cat<<’wendao’关闭变量替换功能。cat<<-‘wendao’去掉每行之前的tab字符。:<<wendao批注,什么都不做。
二、 变量扩展${var}、命令替换$(command)及算术扩展$((算术式))
1, 变量存在:变量有值或者其值为空(null),若用unset掉变量,则变量不存在。
${变量-默认值}:若变量存在返回变量值,否则就返回默认值。
${变量:-默认值}:若变量不存在或者为空就传回默认值,否则返回变量值。
${变量:=默认值}:若变量不存在或者为空就给变量设一个默认值,否则就返回变量的值。
${变量:?提示信息}:若变量不存在或者其值为空提示错误信息,并停止执行。
${变量:+真值}:变量存在且其值非空则返回真值,否则返回空值。
:表明同时测试空值,若去掉:表示只测存在性,不测空值。
2, 变量扩展:字符串第一个字符编号为0,依次累加。
${变量:位置起点:长度}:从位置起点开始截取字符串,若没有长度则取以后的全部字符。${@:起点:个数}:截取位置参数,若无个数则取以后所有的参数。
${#变量名称}:返回变量值的字符串长度。
${#数组[@]}:取数组元素个数
${#数组[*]}:取数组元素个数
expr length “字符串”:获取字符串长度
expr “字符串”:”.*”:利用字符串匹配来计算字符串的长度
${变量#样式}:从变量的左边开始比较样式,删除最短符合样式的字符串
${变量##样式}:从变量的左边开始比较样式,删除最长符合样式的字符串
${变量%样式}:从变量的右边开始比较样式,删除最短符合样式的字符串
${变量%%样式}:从变量的右边开始比较样式,删除最长符合样式的字符串
${变量/样式/替换字符串}:只替换第一个对比符合样式的字符串
${变量//样式/替换字符串}:替换全部符合样式的字符串
若替换字符串为空则为删除符合样式的字符串,若样式前加#表示该样式必须出现在变量的开头,若加上%表示该样式必须出现在变量的末尾。
若将变量名换为@或者*表示会把各位置参数轮流对比样式进行替换操作。
${!开头字符串@}或者${!开头字符串*}:列出所有以”开头字符串”开头的变量名称,各变量之间用$IFS定义的第一个分隔符隔开。
${!数组[@]}或者${!数组[*]}:列出数组所有的索引,各索引之间用$IFS的第一个分隔符隔开,若将${!数组[@]}用双引号引起来,返回的值不是一个字符串,而是将各个索引值视为单独的字符串。
3、命令替换:将命令执行后的输出放入变量中,会自动删除换行符,有以下两种写法:
变量名称=$(命令) 【推荐写法】
变量名称=`命令`
在获取命令执行结果的时候会自动删除换行符,可用IFS变量替换换行符。
在命令替换里也可以使用其他的命令替换,如r=$(du –s $(pwd))
3,算术扩展:I=$((4+5))会计算值,否则会当成一个字符串,如I=4+5,实际上I的值为“4+5”字符串。
三、 算术运算:常用的几种方法如下
1,算术式可包含变量、变量扩展,在进行计算时变量会被替换,变量扩展会被展开。
求值时若算术式中的变量不存在或者空值,则该变量的值为0.
以0开头为八进制,以0x或者0X开头为16进制,不同进制的数字可以”进制#数字”的表示法。
在$((表达式中))如果表达式中的变量,最好不要加$,以免该变量不存在造成语法错误,若表达式中有变量扩展则要加上$,如推荐用$((12+i)),不推荐用$((12+$i))。
常用的算术运算符:
++/--自增和自减、*乘、/除、**乘方、%求余、<<位左移、>>位右移、|位或、&位与。
+=、-=、*=、/=等赋值运算符。
三元运算符:((n<100?45:89))
2、expr作表达式时,如果达表式中含有bash shell的特殊字符,如*、|、<、>、!、&、(、)的话要进行转义,否则会错。
r=`expr 参数1\| 参数2`:若参数1存在、非空、非0则传回参数1的值,否则传回参数2的值。
r=`expr 参数1 \& 参数2`:若参数1和参数2都存在、非空、非0,则返回参数1的值,否则返回0。
r=`expr 4+5`:加法运算。 r=`expr 4-5`:减法运算。r=`expr 4 \* 5`:乘法运算。
r=`expr 4 % 5`:求余运算。 r=`expr 4 / 5`:除法运算。r=`expr $r+1`:递加1。
r=`expr “string”:st`:对比样式st符合的字符数,此处符合2个字符,故r值为2.
r=`expr match “string” st`与上式一样。
r=`expr index “string” in`:找出子串在字符串中的位置。此处为3,即in在string中的位置为3.
r=`expr substr “string” 2 3`:从第2个字符开始取3个字符的长度。
r=`expr length “string”`:计算字符串的长度。
r=`expr + match`:+后接要视为一般字符的关键词或者运算符,如 / 等。
r=`expr 1\< 2`成立并返回1。r=`expr 3 \<= 2`不成立返回0。r=`expr 2=2`成立并返回1。
r=`expr 3 \!= 2`成立并返回1。r=`expr 3\>= 2`成立并返回1.r=`expr 3 \> 2`成立并返回1。
注:expr不支持乘方运算。
3、使用$[ ]做算术运算
r=$[算术式]:r=$[4+-*/%5]4加减乘除求余5.
r=$[2**3]乘方运算。r=$[r+1]递加运算。
4、使用内置命令declare、let做算术运算:在用这两个命令时,运算符和操作数之间不可以有空格,要紧密相连。特殊符号不必转义,如乘法*、乘方**直接就可以用,在算式中可以包含其他变量,变量之前不用加$符号。
declare设定变量后运算就比较直观了,如declare –I x.x=5*7。x=2**3,
let指令也是如此,如let I=6+4;let I=2**3。
使用空格符可增强可读性,但这时要加双引号,如let “I = I + 5”
四、 流程控制语句:用break和continue语句可跳出循环。
1, if判断语法:
Ø 这里的条件测试可为一条命令,包括管道命令,执行成功则返回真,如if grep –q “str” wendao.txt;then 就是查到wendao.txt里是否包含str这个字符串,若成就判真。
Ø 如if ((a<b));then 这里((算术式))是复合命令的内置算式,它等同于let “算式”:if let “a<b”.
其他的如:((0))、((1))、((5*6))、((20<30))、((20&&30))、((10&3))、((2|5))。结果为0就判断为假,非0就判断为真。
Ø 还可以使用[[ 判断式 ]],注意这里的空格,如if [[ str > xyz ]];then
Ø 使用内置命令:test判断式,如if test “str” \> “xyz”;then
Ø 使用内置命令:[ 判断式 ],与test用法相同,两者可改写,如if [ “str” \> “xyz” ];then
Ø 作用-a、-o进行逻辑组合:
[ -r filename1 -a -x filename1 ]:-a有且之意,filename1可读并且可执行时满足条件。
[ -r filename1 -o -x filename1 ]:-o有或之意,filename1可读或者可执行时满足条件。
Ø 命令1 && 命令2:如果命令1执行成功才会执行命令2,如果两个命令都执行成功返回真值,否则就返回假值。
Ø 命令1 || 命令2:如果命令1执行失败才会执行命令2,如果两者有一个执行成功就返回真,否则返回假值。
注意:[[ ]] 和 (( ))都不必转义运算符。在[[ ]]中如果使用==或者!=,且在这两个运算符的右方的字符串没有加上单引号或者双引号,则==或者!=会视为想要对比该字符串所形成的”样式”,如果相符返回真值,如 [[ $a == “???” ]]、[[ $a == ??? ]] 是不一样的。其中 =~ 右边放想要对比的正则表达式样式,[[ $a =~ .{3} ]] 注意此样式不要加引号。
Ø 有关文件属性的判断:
Ø 有关字符串的判断:变量名上最好加双引号,以免变量内容为空时造成语法错误。
Ø 算式的条件判断:参数1 -eq 参数2
-eq:相等。-ne:不相等。-lt:小于。-gt:大于。-le:小于等于。-ge:大于等于。
Ø bash选项判断式:-o set 选项名称:如果该选项是开启的状态。
2、 case条件判断式的结构如下(相当于其他语言中的switch)
Ø 若样式串行中有好几个字符串要对比,要使用 | 隔开,为或的意思,只要符合其一就算对比成功。
Ø 样式串行可写成 ‘(样式串行)’ 或者写成 ‘样式串行)’,一般写成后面的。
Ø 样式 串行可包括字符串,如jack。通配符:C*匹配以C开头的字符串。字符集合:[p-r]im表示pim、qim、rim三个串。
Ø ?(样式串行):匹配0次或者1次样式串行。
*(样式串行):匹配>=0次样式串行。
+(样式串行):匹配>=1次样式串行。
@(样式串行):符合样式串行中的一个就算对比符合。
!(样式串行):只要不是出现在样式串行中的就算对比符合。
以上这些除可用于case语法外,还可以用在[[ ]]判断中,if [[ $cmd == @(declare|export) ]];then。
3、 for循环:串行就是用$IFS所定义的分隔符隔开的字符串组合,以下为两种写法:
4、 while循环,语法如下:
5、 until循环:与while循环刚好相反,当条件测试值为假的时候才会进入循环。
6、 select选择列表:
select命令用来建立一个选项列表,列表提示符由内置变量$PS3定义,默认是#?,select会给各选项一个编号,由1开始递增,当健入编号选择其中某一选项时,该选项的内容就赋给选项变量,而健入的编号则赋值给REPLY变量中。
五、 函数:函数名 参数1 参数2 参数3……
1、 在使用函数前一定要定义函数,否则会报找不到函数的错误。
2、 在函数执行期间,FUNCNAME表示当前执行的函数,最后一条命令的执行状态代表函数的返回值,如果有return则返回,如return 4 返回4。
3、 用unset –f 函数名 取消函数。
4、 函数只在定义的shell中有效,执行时并不开启新的shell环境,若想让定义的函数在子shell中有效,可用内置命令export –f 选项。
5、 如果没有特别指定,在script中定义的变量为全局变量,在整个脚本文件里皆有效,若想定义函数的私有变量,可用local命令,如local var=0,在函数外就访问不了。
6、 当函数借用命令行参数时,原有的位置参数会被保存起来,等函数执行结束后再恢复其值。
7、 各参数变量:$0:script文件本身,$1:第一个参数,$2:第二个参数,….$9:第9个参数,${10}第10个参数,$#:参数的个数,$@:所有以空白隔开的参数,$*:所有的参数组成的字符串。
六、输出转向操作:
1,操作系统默认指定的3个文件代码:0标准输入(stdin)、1标准输出(stdout)、2标准错误(stderr),转向时 < 代表转向输入,若<左方的文件代码省略默认为0即标准输入,> 代表转向输出,若>左方的文件代码省略,默认为1即标准输出。
2,开启文件,fnu<>文件,开启一个文件,指定其文件代码为fnu,如exec 6<>test.txt开启文件test.txt并指定其文件代码为6。
3,关闭文件,fnu<&- 关闭转向输入文件,如 exec 6<&- 关闭文件代码6,fnu>&- 关闭转向输出文件,如exec 5>&- 关闭文件代码5。
4,复制文件代码,有时为了不影响原有文件代码的使用最好先复制一份,等操作结束再还原回去。
n<&m 复制转向输入的文件代码m,存成文件代码n,使n连接至m。
n>&m 复制转向输出的文件代码m,存成文件代码n,使n连接至m。
exec >&6 将标准输出连接至代码6,凡是原本在标准输出的内容全转存至文件代码6。
cat <&6 将文件代码6的内容转向至标准输入,并有cat把内容显示出来。
exec 5<&0 复制标准输入存成文件代码5,建立文件代码0的连接,就是做输入的备份,一旦备份好后就可以对标准输入进行操作,如转向输入,操作完后应还原标准输入,如 exec 0<&5 5<&- :还原并关闭连接。
5,转向输入:
fnu<文件:wc –l </etc/error.log此处fnu默认为0即标准输入,将标准输入和error.log建立链接,wc改由error.log读取行数。wc并不知道它是从哪里取得数据,反正wc默认就是从标准输入读取数据。
exec 6< /etc/error.log
wc –l <&6
使用文件代码6作输入,来源是error.log,由文件代码6供应wc数据行。
6,转向输出:
fnu>文件:使用文件做转向输出,若文件不存在则创建一个新文件,若存在则清空文件。fnu省略的话默认为1.如产生空文件可以用 > test.txt或者:> test.txt
fnu >| 文件:此语法不理会noclobber选项,只要文件存在就强制覆盖并清空该文件。
7,转向附加: fun>>文件,若文件存在,就写在文件后面,不会清空文件。
8,标准错误伴随标准输出做转向:&>文件 或者 >&文件
ntpdate time.stdtime.gov.cn &>/dev/null
使用ntpdate向ntp主机校时,如果执行时产生错误信息,则伴随执行过程产生的信息,转向输出至/dev/null,即屏弃错误信息。
&>的作用和 “ >文件 2>&1”的作用是相同的,意为转向输出至文件,标准错误代码2连接至标准输出1,如上例可写为:ntpdate time.stdtime.gov.cn > /dev/null 2>&1
9,Here Document的转向:
exec 6<<wendao
line1
line2
wendao
1, 用的时候可以写为$var或者${var},但当变量后有字母或者其他字符时必须用后者。
2, 用printf打印时变量最好用””,如printf “%s\n” “$var”
3, 取消变量,var= 或者unset var(先尝试取消变量否则就取消函数,-f代表函数,-v代表变量,如unset –f fn)
4, 在双引号中,可以替换变量、替换命令执行结果、替换算术运算结果。若在双引号中用\可抑制变量的替换。
5, 变量的作用范围:仅限于当前的shell,但环境变量可以在任何shell环境中有效。在执行sh文件时会另开一个shell环境,从当前环境中继承环境变量。要想在当前shell中运行必须用. cd.sh或者sourec cd.sh。
6, 环境变量:要把一个变量变成环境变量要用export,如export var =”hello”或者export var.
执行export或者export -p会列出目前的环境变量。declare –x var一样可以设为环境变量。
7, BASH内置的环境变量:
BASH:bash完整的变量名,如/bin/bash 或者 /usr/local/bin/bash
BASH_EVN:执行shell script时若此变量不为空则首先执行它。
BASH_VERSION:bash的版本
CAPATH:cd命令搜索的路径(类似在环境变量中搜索命令)
EVN:以互动模式调用sh或者在POSIX模式下时,首先检查此变量,有则首先执行它
EUID:有效的uid
FCEDITOR:fc命令默认使用的比较器
FIGNORE:在进行文件名自动 补齐时,忽略的扩展名列表。用:隔开,如”.o:~:.txt”
FUNCNAME:函数执行时的函数名(类似于php中的魔术变量__FUNCTION__)
GLOBIGNORE:做样式比较时忽略的文件名列表,用:隔开
GROUPS:数组变量,包含用户所属的组群列表
HISTCMD:当前指令执行完后它在历史指令中的排列编号,
HISTCONTROL:控制指令是否存入历史脚本文件中
ignorespace:排除开头有空格的指令
ignoredups:连续重复的指令只存一个
ignoreboth:结合前两者的功能
HISTFILE:设定历史脚本文件的路径文件名,通常是~/.bash_history
HISTFILESIZE:历史脚本文件存储指令的最大行数,默认500
HISTIGNORE:不存入历史的指令,以:隔开,如ls:ps:cd:t*:\&(&代表最后一个历史指令,若一直健入重复的指令只存入一个,&又是后台执行符号,需要用\转义)
HISTSIZE:在互动模式中shell记住的历史指令数目,默认500
HOME:当前用户的家目录
HOSTFILE:包含自动补齐主机名的数据文件,须和/etc/hosts格式相同
HOSTNAME:主机名称
HOSTTYPE:主机形态,如i386
IFS:定义字段分隔符,默认为:空格、tag字符、换行字符。
IGNOREEOF:在按Ctrl+D时,出现几次EOF才能注销系统。
INPUTRC:设定命令行函数库readline的启动配置文件,可覆盖~/.inputrc
LANG:目前语系的名称
LC_ALL:目前的locale,可覆盖LAND和LC_*的设定
LC_COLLATE:locale字母排序
LC_CTYPE:locale字符分类
LC_MESSAGES:locale信息显示的转换,如
LINENO:script脚本已执行到的行数
MACHTYPE:描述主机型态的GUN格式,如i386-pc-linux-gun
MAIL:邮件文件的名称
MAILCHECK:每隔多久检查一下邮件,默认是60秒
MAILPATH:设定检查新邮件的文件名,多个用:隔开
OLDPATH:前一个工作目录(有点类似于cd -)
OPTARG:使用getopts处理选项时,取得的选项的参数
OPTERR:若此值为1,当getopts发生错误时,不管选项行第一个字符是否为:,都显示错误信息
OSTYPE:操作系统,如linux-gun
PATH:命令搜索的路径,多个用:隔开
PPID:父进程编号
PROMPT_COMMAND:出现在主要提示符$PS1之前执行的命令
PS1:默认为\s-\v\$ <主要提示符代码见背部>
PS2:次提示符号,默认为>
PS3:select选单的提示符,默认为#?
PS4:追踪程序时各行的提示符样式,默认为+,
PWD:当前的工作目录
RANDOM:产生随机数(需要随机种子)
REPLY:在select和read没有设定读取的变量时,默认的变量名称
SECONDS:目前的shell script已执行的时间(以秒为单位)
SHELL:shell的文件路径,默认为”/bin/bash”
SHELLOPTS:经set –o指令开启的shell选项,以:分隔
SHLVL:子shell的层级数
TIMEFORMAT:设定time统计运行时间的格式《更详细的见背后》
TMOUT:shell脚本执行的超时时限
UID:用户ID
$1~$n:位置参数,传入脚本或者函数的参数,第一个参数是$1,第二个是$2,依次类推,第10个是${10},$0表示执行程序的名称
$*:代表所有位置的参数,为一字符串,如”ABC 123 XYZ”
$@:所有位置的参数组成的串行,如”ABC”、”123”、”XYZ”
$#:位置参数的个数
$?:上一个命令执行结束后的传回值,0代表执行成功,非0代表失败
$$:目前shell script的进程编号
$!:上一个后台程序的进程编号
$_:1,script执行时为bash的绝对路径,如/bin/bash。2,上一个命令执行时最后一个位置参数。3,检查邮件时,为邮件文件名。
8, 设变量为只读变量
readonly var设定var变量为只读,执行readonly或者readonly –p列出所有的只读变量。
readonly –f 函数名:设定函数只读,不可修改。
readonly –a 数组名:设定数组只读,不可修改。
或者declare –r var设定var只读
9, declare 用法:
选项 | 说明 |
-p | 显示变量属性 Declare –p var 显示var的属性 |
-a | 变量是一个数组 Declare –a array 设定array为一个数组 |
-f | 搜寻命令时只找函数 Declare –f fn 寻找fn时只在函数列表里找,不搜寻其他别名或者外部命令 |
-i | 变量是一个整数 Declare –I var 设定var为一整数 |
-F | 显示所有的函数名称及其属性 Declare -F |
-r | 设定变量只读 Declare –r var Var变量只读 |
-t | 设定变量具有trace属性,有利于排除。declare –t xyz=111 |
-x | 设为环境变量,declare –x mypath |
大多数主机在开设帐号后会自动在主目录下建立.bash_profile和.bashrc这两个文件,至于.bash_logout一般默认没有,需要自己建立。一般在.bash_profile中设定全局适用的命令、搜寻路径和环境变量,而其他大部分设定在.bashrc里,所以.bash_profile比较小,而.bashrc比较大。
文件名 | 执行时机 |
~/.bash_profile | 登录时 |
~/.bashrc | 执行shell script时 |
~/.bash_logout | 注销时 |
/etc/profile
/etc/bash.bashrc
/etc/skel目录下所有的文件
其中/etc/profile和/etc/bash.bashrc的设定会影响所有的账号使用。在/etc/profile中设定的有umask、PATH、多国语言环境、提示符号、别名等。/etc/bash.bashrc的内容大外如下:[ -f /etc/profile ] && . /etc/profile 表示当执行交互式的shell时会检查/etc/profile是否存在,若存在就执行。
/etc/skel的作用是:当管理员开设新账号时,这个目录下的所有的文件会拷一份到新账号home目录下,作为用户的环境文件。其中包括 .bash_profile和.bashrc文件。
11,数组:第一个元素由0开始,并且如1+2这样的算术表达式也可以作为索引,${arr[5]}.
建立数组时可以指定个别元素的索引,如arr=([3]=77 [5]=100 55)第4个元素为77,第6个元素为100第7全元素为55.
$(arr[@])一次取出数组的全部元素,得到以空白隔开的全部元素,如77 100 55
$(arr[*])一次取出数组的全部元素,得到一个字符串,如”77 100 55”
$(#arr[@])或者 $(#arr[*])取得数组元素的个数
unset arr取消数组
unset arr[4]取消数组的一个元素
11, Here Document:cat<<’wendao’关闭变量替换功能。cat<<-‘wendao’去掉每行之前的tab字符。:<<wendao批注,什么都不做。
二、 变量扩展${var}、命令替换$(command)及算术扩展$((算术式))
1, 变量存在:变量有值或者其值为空(null),若用unset掉变量,则变量不存在。
${变量-默认值}:若变量存在返回变量值,否则就返回默认值。
${变量:-默认值}:若变量不存在或者为空就传回默认值,否则返回变量值。
${变量:=默认值}:若变量不存在或者为空就给变量设一个默认值,否则就返回变量的值。
${变量:?提示信息}:若变量不存在或者其值为空提示错误信息,并停止执行。
${变量:+真值}:变量存在且其值非空则返回真值,否则返回空值。
:表明同时测试空值,若去掉:表示只测存在性,不测空值。
2, 变量扩展:字符串第一个字符编号为0,依次累加。
${变量:位置起点:长度}:从位置起点开始截取字符串,若没有长度则取以后的全部字符。${@:起点:个数}:截取位置参数,若无个数则取以后所有的参数。
${#变量名称}:返回变量值的字符串长度。
${#数组[@]}:取数组元素个数
${#数组[*]}:取数组元素个数
expr length “字符串”:获取字符串长度
expr “字符串”:”.*”:利用字符串匹配来计算字符串的长度
${变量#样式}:从变量的左边开始比较样式,删除最短符合样式的字符串
${变量##样式}:从变量的左边开始比较样式,删除最长符合样式的字符串
${变量%样式}:从变量的右边开始比较样式,删除最短符合样式的字符串
${变量%%样式}:从变量的右边开始比较样式,删除最长符合样式的字符串
${变量/样式/替换字符串}:只替换第一个对比符合样式的字符串
${变量//样式/替换字符串}:替换全部符合样式的字符串
若替换字符串为空则为删除符合样式的字符串,若样式前加#表示该样式必须出现在变量的开头,若加上%表示该样式必须出现在变量的末尾。
若将变量名换为@或者*表示会把各位置参数轮流对比样式进行替换操作。
${!开头字符串@}或者${!开头字符串*}:列出所有以”开头字符串”开头的变量名称,各变量之间用$IFS定义的第一个分隔符隔开。
${!数组[@]}或者${!数组[*]}:列出数组所有的索引,各索引之间用$IFS的第一个分隔符隔开,若将${!数组[@]}用双引号引起来,返回的值不是一个字符串,而是将各个索引值视为单独的字符串。
3、命令替换:将命令执行后的输出放入变量中,会自动删除换行符,有以下两种写法:
变量名称=$(命令) 【推荐写法】
变量名称=`命令`
在获取命令执行结果的时候会自动删除换行符,可用IFS变量替换换行符。
在命令替换里也可以使用其他的命令替换,如r=$(du –s $(pwd))
3,算术扩展:I=$((4+5))会计算值,否则会当成一个字符串,如I=4+5,实际上I的值为“4+5”字符串。
三、 算术运算:常用的几种方法如下
名称 | 语法 | 范例 |
算术扩展 | $((算术式)) | R=$((3+5*7)) |
使用外部程序expr | R=`expr 4+5` | R=`expr 4+5` |
使用$[ ] | $[算术式] | R=$[4+5] |
使用内置命令declare | Declare –i 变量=算术式 | Declare –I r=4+5 |
使用内置命令let | Let 算术式 | Let r=5+4 |
求值时若算术式中的变量不存在或者空值,则该变量的值为0.
以0开头为八进制,以0x或者0X开头为16进制,不同进制的数字可以”进制#数字”的表示法。
在$((表达式中))如果表达式中的变量,最好不要加$,以免该变量不存在造成语法错误,若表达式中有变量扩展则要加上$,如推荐用$((12+i)),不推荐用$((12+$i))。
常用的算术运算符:
++/--自增和自减、*乘、/除、**乘方、%求余、<<位左移、>>位右移、|位或、&位与。
+=、-=、*=、/=等赋值运算符。
三元运算符:((n<100?45:89))
2、expr作表达式时,如果达表式中含有bash shell的特殊字符,如*、|、<、>、!、&、(、)的话要进行转义,否则会错。
r=`expr 参数1\| 参数2`:若参数1存在、非空、非0则传回参数1的值,否则传回参数2的值。
r=`expr 参数1 \& 参数2`:若参数1和参数2都存在、非空、非0,则返回参数1的值,否则返回0。
r=`expr 4+5`:加法运算。 r=`expr 4-5`:减法运算。r=`expr 4 \* 5`:乘法运算。
r=`expr 4 % 5`:求余运算。 r=`expr 4 / 5`:除法运算。r=`expr $r+1`:递加1。
r=`expr “string”:st`:对比样式st符合的字符数,此处符合2个字符,故r值为2.
r=`expr match “string” st`与上式一样。
r=`expr index “string” in`:找出子串在字符串中的位置。此处为3,即in在string中的位置为3.
r=`expr substr “string” 2 3`:从第2个字符开始取3个字符的长度。
r=`expr length “string”`:计算字符串的长度。
r=`expr + match`:+后接要视为一般字符的关键词或者运算符,如 / 等。
r=`expr 1\< 2`成立并返回1。r=`expr 3 \<= 2`不成立返回0。r=`expr 2=2`成立并返回1。
r=`expr 3 \!= 2`成立并返回1。r=`expr 3\>= 2`成立并返回1.r=`expr 3 \> 2`成立并返回1。
注:expr不支持乘方运算。
3、使用$[ ]做算术运算
r=$[算术式]:r=$[4+-*/%5]4加减乘除求余5.
r=$[2**3]乘方运算。r=$[r+1]递加运算。
4、使用内置命令declare、let做算术运算:在用这两个命令时,运算符和操作数之间不可以有空格,要紧密相连。特殊符号不必转义,如乘法*、乘方**直接就可以用,在算式中可以包含其他变量,变量之前不用加$符号。
declare设定变量后运算就比较直观了,如declare –I x.x=5*7。x=2**3,
let指令也是如此,如let I=6+4;let I=2**3。
使用空格符可增强可读性,但这时要加双引号,如let “I = I + 5”
四、 流程控制语句:用break和continue语句可跳出循环。
1, if判断语法:
if 条件测试1;then 命令区域1 elif 条件测试2;then 命令区域2 else 命令区域3 fi | If 条件测试1 Then 命令区域1 Elif 条件测试2 Then 命令区域2 Else 命令区域3 fi |
Ø 如if ((a<b));then 这里((算术式))是复合命令的内置算式,它等同于let “算式”:if let “a<b”.
其他的如:((0))、((1))、((5*6))、((20<30))、((20&&30))、((10&3))、((2|5))。结果为0就判断为假,非0就判断为真。
Ø 还可以使用[[ 判断式 ]],注意这里的空格,如if [[ str > xyz ]];then
Ø 使用内置命令:test判断式,如if test “str” \> “xyz”;then
Ø 使用内置命令:[ 判断式 ],与test用法相同,两者可改写,如if [ “str” \> “xyz” ];then
Ø 作用-a、-o进行逻辑组合:
[ -r filename1 -a -x filename1 ]:-a有且之意,filename1可读并且可执行时满足条件。
[ -r filename1 -o -x filename1 ]:-o有或之意,filename1可读或者可执行时满足条件。
Ø 命令1 && 命令2:如果命令1执行成功才会执行命令2,如果两个命令都执行成功返回真值,否则就返回假值。
Ø 命令1 || 命令2:如果命令1执行失败才会执行命令2,如果两者有一个执行成功就返回真,否则返回假值。
注意:[[ ]] 和 (( ))都不必转义运算符。在[[ ]]中如果使用==或者!=,且在这两个运算符的右方的字符串没有加上单引号或者双引号,则==或者!=会视为想要对比该字符串所形成的”样式”,如果相符返回真值,如 [[ $a == “???” ]]、[[ $a == ??? ]] 是不一样的。其中 =~ 右边放想要对比的正则表达式样式,[[ $a =~ .{3} ]] 注意此样式不要加引号。
Ø 有关文件属性的判断:
判断式 | 含义 |
-a 文件 | 若文件存在 |
-b 文件 | 若文件存在,且该文件是区域设备文件 |
-c 文件 | 若文件存在,且该文件是字符设备文件 |
-d 文件 | 若文件存在,且该文件是目录 |
-e 文件 | 若文件存在 |
-f 文件 | 若文件存在,且该文件是一般文件 |
-g 文件 | 若文件存在,且设置了set group id属性 |
-h 文件 | 若文件存在,且是符号链接文件 |
-k 文件 | 若文件存在,且设置了sticky位的属性 |
-p 文件 | 若文件存在,且是管道文件 |
-r 文件 | 若文件存在,且具有可读的属性 |
-s 文件 | 若文件存在,且文件大小大于0 |
-t 文件描述符 | 若文件描述符是开启的,且链接了某一个终端 |
-u 文件 | 若文件存在,且设置了set user id 属性 |
-w 文件 | 若文件存在,且具有可写的属性 |
-x 文件 | 若文件存在,且具有可执行的权限 |
-O 文件 | 若文件存在,且该文件为有效的用户id所拥有 |
-G 文件 | 若文件存在,且该文件为有效的群组id所拥有 |
-L 文件 | 若文件存在,且为符号链接文件 |
-S 文件 | 若文件存在,且为socket文件 |
-N 文件 | 若文件存在,且自从上次读取后被修改过 |
文件1 –nt 文件2 | 若文件1比文件2新。或者文件1存在但文件2不存在 |
文件1 –ot 文件2 | 若文件1比文件2旧。或者文件2存在但文件1不存在 |
文件1 –ef 文件2 | 若文件1和文件2链到相同的设备和inode编号 |
判断式 | 含意 |
-z 字符串 | 若字符串长度为0(空串) |
-n 字符串 | 若字符串长度不为0,即非空串 |
字符串 | 若字符串长度不为0 |
字符串1 == 字符串2 (或者用 = ) | 若两个字符串相等 |
字符串1 != 字符串2 | 若两个字符串不相等 |
字符串1 < 字符串2 | 若串1小于串2 |
字符串1 > 字符串2 | 若串1大于串2 |
-eq:相等。-ne:不相等。-lt:小于。-gt:大于。-le:小于等于。-ge:大于等于。
Ø bash选项判断式:-o set 选项名称:如果该选项是开启的状态。
2、 case条件判断式的结构如下(相当于其他语言中的switch)
Case 待选项 in 样式串行1) 命令区域1;; 样式串行2) 命令区域2;; 样式串行3) 命令区域3;; …………. *) 命令区域;; esac |
Ø 样式串行可写成 ‘(样式串行)’ 或者写成 ‘样式串行)’,一般写成后面的。
Ø 样式 串行可包括字符串,如jack。通配符:C*匹配以C开头的字符串。字符集合:[p-r]im表示pim、qim、rim三个串。
Ø ?(样式串行):匹配0次或者1次样式串行。
*(样式串行):匹配>=0次样式串行。
+(样式串行):匹配>=1次样式串行。
@(样式串行):符合样式串行中的一个就算对比符合。
!(样式串行):只要不是出现在样式串行中的就算对比符合。
以上这些除可用于case语法外,还可以用在[[ ]]判断中,if [[ $cmd == @(declare|export) ]];then。
3、 for循环:串行就是用$IFS所定义的分隔符隔开的字符串组合,以下为两种写法:
For 变量 in 串行 Do 命令区域 done | IFS=’:’ PL=”root:x:0:0:/bin/bash” for f in $PL do echo $f done |
For ((初始条件; 终止条件; 异动项)) Do 命令区域 done | Declare –i i sum For ((i=1;i<=20;i=i+1)) Do Let sum+=i done |
While 条件测试 Do 命令区域 done | While ((i < 10)) Do Let ++i done |
While read line Do Echo $line Done < cvsfile | IFS=’:’ While read f1 f2 f3 f4 f5 f6 f7 Do Echo “账号:$f1” Done < “/etc/passwd” |
IFS=’:’ Cat /etc/passwd |{ While read f1 f2 f3 f4 f5 f6 f7 Do Echo “账号:$f1” done } |
Until 条件测试 Do 命令区域 done |
Select 选项变量 in 串行 Do 命令区域 done |
五、 函数:函数名 参数1 参数2 参数3……
Function 函数名() { } | 函数名() { } | Function 函数名 { } |
2、 在函数执行期间,FUNCNAME表示当前执行的函数,最后一条命令的执行状态代表函数的返回值,如果有return则返回,如return 4 返回4。
3、 用unset –f 函数名 取消函数。
4、 函数只在定义的shell中有效,执行时并不开启新的shell环境,若想让定义的函数在子shell中有效,可用内置命令export –f 选项。
5、 如果没有特别指定,在script中定义的变量为全局变量,在整个脚本文件里皆有效,若想定义函数的私有变量,可用local命令,如local var=0,在函数外就访问不了。
6、 当函数借用命令行参数时,原有的位置参数会被保存起来,等函数执行结束后再恢复其值。
7、 各参数变量:$0:script文件本身,$1:第一个参数,$2:第二个参数,….$9:第9个参数,${10}第10个参数,$#:参数的个数,$@:所有以空白隔开的参数,$*:所有的参数组成的字符串。
六、输出转向操作:
1,操作系统默认指定的3个文件代码:0标准输入(stdin)、1标准输出(stdout)、2标准错误(stderr),转向时 < 代表转向输入,若<左方的文件代码省略默认为0即标准输入,> 代表转向输出,若>左方的文件代码省略,默认为1即标准输出。
2,开启文件,fnu<>文件,开启一个文件,指定其文件代码为fnu,如exec 6<>test.txt开启文件test.txt并指定其文件代码为6。
3,关闭文件,fnu<&- 关闭转向输入文件,如 exec 6<&- 关闭文件代码6,fnu>&- 关闭转向输出文件,如exec 5>&- 关闭文件代码5。
4,复制文件代码,有时为了不影响原有文件代码的使用最好先复制一份,等操作结束再还原回去。
n<&m 复制转向输入的文件代码m,存成文件代码n,使n连接至m。
n>&m 复制转向输出的文件代码m,存成文件代码n,使n连接至m。
exec >&6 将标准输出连接至代码6,凡是原本在标准输出的内容全转存至文件代码6。
cat <&6 将文件代码6的内容转向至标准输入,并有cat把内容显示出来。
exec 5<&0 复制标准输入存成文件代码5,建立文件代码0的连接,就是做输入的备份,一旦备份好后就可以对标准输入进行操作,如转向输入,操作完后应还原标准输入,如 exec 0<&5 5<&- :还原并关闭连接。
5,转向输入:
fnu<文件:wc –l </etc/error.log此处fnu默认为0即标准输入,将标准输入和error.log建立链接,wc改由error.log读取行数。wc并不知道它是从哪里取得数据,反正wc默认就是从标准输入读取数据。
exec 6< /etc/error.log
wc –l <&6
使用文件代码6作输入,来源是error.log,由文件代码6供应wc数据行。
6,转向输出:
fnu>文件:使用文件做转向输出,若文件不存在则创建一个新文件,若存在则清空文件。fnu省略的话默认为1.如产生空文件可以用 > test.txt或者:> test.txt
fnu >| 文件:此语法不理会noclobber选项,只要文件存在就强制覆盖并清空该文件。
7,转向附加: fun>>文件,若文件存在,就写在文件后面,不会清空文件。
8,标准错误伴随标准输出做转向:&>文件 或者 >&文件
ntpdate time.stdtime.gov.cn &>/dev/null
使用ntpdate向ntp主机校时,如果执行时产生错误信息,则伴随执行过程产生的信息,转向输出至/dev/null,即屏弃错误信息。
&>的作用和 “ >文件 2>&1”的作用是相同的,意为转向输出至文件,标准错误代码2连接至标准输出1,如上例可写为:ntpdate time.stdtime.gov.cn > /dev/null 2>&1
9,Here Document的转向:
exec 6<<wendao
line1
line2
wendao
相关文章推荐
- linux学习笔记:shell脚本编程相关(上)
- Shell 编程-学习笔记
- Linux命令与shell脚本编程学习笔记-16创建函数
- shell脚本编程之case语句学习笔记
- 学习笔记: shell 编程中空格的使用
- shell脚本编程之循环语句学习笔记
- 嵌入式开发之linux基础第七天学习笔记 shell脚本编程(二)
- shell脚本编程之if语句学习笔记
- shell脚本编程之if语句学习笔记
- shell 编程学习笔记(一)
- Shell 编程学习笔记:条件测试
- Linux学习笔记(8)之Shell编程入门--输入输出、引号
- shell 编程学习笔记 (三)
- Linux命令行与Shell脚本编程[学习笔记1]
- Liunx 命令行与shell脚本编程大全 第八章学习笔记(Linux系统的包管理基础)
- shell 编程学习笔记(二)
- shell脚本编程之循环语句学习笔记
- Shell 编程学习笔记
- Linux Shell编程学习笔记一:shell简介
- Shell 编程学习笔记:脚本输入参数