首页 | 新闻 | 交流 | 问吧 | 文档 | 手册 | 下载 | 博客

高级bash编程指南(九)

作者:  时间: 2011-03-20

一 函数

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