高级bash编程指南(九)
一 函数
1.在调用函数之前必须先要定义函数
2.函数的嵌套,但是并不常用
eg f1()
{
f2()
{echo "f2"}
}
f2 #在此处调用f2会出现错误。
f1 #什么也不做,并不会调用f2
f2 #此时可以正确调用f2了,因为之前调用f1使
f2在脚本中变得可见了
先面对比的看另一例子
func()
{
var=100
}
echo $var #null
func
echo $var #100
3. 向函数传递参数
#!/bin/bash
func()
{
echo "$1" #这里并不是传递给该脚本的位置参数
}
func "nihao"
exit 0
4.变量替换
message=hello
hello=goodbye
echo ${message} #hello
echo ${!message} #goodbye
5.函数退出码
(1)return statement(0-255,不能是负数,当大于255时,对256取余
256=0,258=2),否则函数退出码时函数最后一个执行命令的退出码,
$?保存退出码
(2)命令替换得到返回值
func()
{
echo "$1"
}
var=$(func 100 )
6.函数重定向
func
{
echo "jfdshld"
}>$filename
二 局部变量
1.Bash中局部变量,全局变量的概念同C语言中的变量还是有很大不同,
在Bash中只有用local来声明的变量才是局部变量,只是在该变量声明
的代码块中可见。即使在在函数中声明的变量(没加local)也是全局变量。
2.局部变量可以递归,但是在shell中用递归时不推荐的,因为效率太低。
三 别名
Bash别名本质是一个简写,可以避免键入过长的命令序列。我们以添加
alias lm="ls -l|more" (单引号也可以),alias rm='rm -i'(交互式删除)。
到文件~/.bashrc里,该文件默认就有好多alias。eg :
alias ll='ls -alF' alias la='ls -A' alias l='ls -CF'
在脚本里,别名机制其实并不是很常用,有好多限制。
Bash不能在别名中扩展参数,不能在混合型结构中
使用,egif/then,循环和函数,不能递归扩展。
四 列表结构
与列表(&&)和或列表(||)结构提供了一种处理一串连续命令的方法。它们能有效的替代
复杂的if/then语句,甚至case语句。
与列表和或列表的退出状态时最后一个执行命令的退出状态。
五 数组
1.数组的基本用法
eg arr[11]=23 #数组成员不必一定要连续,可以有空
arr[13]="hello" #数组元素的“类型”可以不同
(1)初始化:arr[num]
(2)声明:declare -a arr
(3)访问数组元素:${arr[num]}
(4)初始化数组的另一种方法 arr=(one two three four)
Bash中数组的索引也是从0开始的。
(5)初始化数组方法三 arr=([12]=one [24]=24)
2.
Bash允许把变量当成数组来操作,即使这个变量没有没有明确的声明为数组
eg
#!/bin/bash
arr[0]=abc123
arr[3]=ABC123
string=abc123
echo ${string[@]} ${arr[@]} #数组中的所有元素
echo ${string[*]} ${arr[*]} #同上
echo ${string[0]} ${arr[1]} #访问数组元素
echo ${#string[@]} ${#arr[@]} #数组中元素的个数,result=2,不是4
echo ${#string[*]} ${#arr[*]} #同上
echo ${#string} ${#arr} #字符串长度,对于数组是数组第一个元素的长度。
${#arr[num]} #数组第(arr+1)个元素的长度
3.大部分标准的字符串操作符可以用于数组操作
arr=(one two three four five)
(1)提取子串
echo ${arr[@]:1} #two three four five
echo ${arr[@]:1:2} #two three
(2)删除子串
echo ${arr[@]#f*e} #one two three four
echo ${arr[@]##f*e} #one two three four
echo ${arr[@]#e*t} #one two three four five ,而非on wo three four five
可以这样理解操作,从数组中的第一个元素进行匹配操作,最终删除最短的匹配
所以不会出现跨元素的进行操作的情况。
%从数组的最后一个数组开始进行匹配。
(3)子串替换
echo ${arr[@]/one/zone} #zone two three four five(替换第一个)
echo ${arr[@]//o/z} #zne twz three fzur five(替换所有)
echo ${arr[@]//fi/} #one two three four ve(删除)
echo ${arr[@]/#o/z} #zne two three four five(匹配开头)
echo ${arr[@]/%o/z} #one twz three four five(匹配结尾)
(4)在数组的环境里,一些Bash内建命令含义有一定的轻微的改变。unset会删除
数组元素或整个数组
unset arr[0] unset arr
4.
(1)arr1=( "${arr[@]} " ) or arr1="${arr[@]}" #赋值数组
(2)arr2[3]=3
echo ${arr2[3]} #3
echo ${arr2[@]} #3
arr2=( “${arr2[@]}” "new" ) or arr2[$arr[*]]="new"
echo ${arr2[@]} #3 new
echo ${arr2[0]} #3 挺奇怪
5.对变量增加declare -a语句声明可以加速后面的数组操作速度。
六 /dev和/proc
1./proc目录实际上是一个伪文件系统。
当执行cat /proc/cpuinfo 显示的内容实际上是linux驱动程序中某一个函数例程
的返回结果。
2./proc目录下有许多不想同的数字命令的子目录。这些子目录的数字名字都映射对应的当前正在运行的进程的进程id。这些子目录里面有许多文件用于保存对应进程的信息。文件stat和status保存着进程运行时的各项统计。
七 关于Zeros和Nulls
1./dev/null "黑洞",
cat /dev/null >/var/log/wtmp #清空日志文件
cat $filename 2>/dev/null #丢掉错误信息
2.产生连续不断的null流(二进制0,不是ascii)
dd if=/dev/zero of=$filename bs=1024 count=100