高级bash编程指南(十)

一 调试

1.设置选项

(1)bash -n scriptname 不会实际运行脚本,而只是检查标本的语法错误,

也可以在脚本中添加 set -n 或者set -o noexec

(2)bash -v scriptname在实际执行一个命令或者脚本前打印出这个命令或者脚本的内容,

也可以在脚本中添加set -v 或者set -o verbose

(3)bash -x scriptname 打印每个命令的执行结果,set -x or set -o xtrace

2.$LINENO和caller

(1)$LINENO 等同与vc中的 __LINE__

(2)caller

#!/bin/bash

func()

{

caller 0

}

func

exit 0

把caller放在函数中,可以输出这个函数在哪一行被调用的,以及是在哪个函数中调用的

以及该脚本被调用时的命令。

eg: 10  main  ./test.sh

3.像C语言中写一个assert函数

#!/bin/bash

assert()

{

E_ARGS=98

E_ASSERT_FSILED=99

if [ -z "$2" ];then

  return $E_ARGS

fi

lineno=$2

if [ ! $1 ];then

  echo "Assertion failed:File \"$0\",line $lineno,\"$1\""

  exit $E_ASSERT_FAILED

fi

}

a=5

b=4

assert  "$a -lt $b" $LINENO

#other command

echo "hello shell"

exit 0

4.trap 捕捉信号

trap 'command' SIG

trap 'echo ctrl-c' 2

trap 2  #恢复

trap 'command' DEBUG  #DEBUG 每执行一行脚本执行一次command

二 Bash选项

用来改变shell或脚本行为的机制

bash [-optiion缩写]  or bash -o [option名称]

缩写名称作用
-C noclobber 防止重定向时覆盖文件 (此作用会被>|覆盖)
-D (none) 列出双引号引起的含有$前缀的字符串,但不执行脚本中的命令
-a allexport 导出所有定义的变量到环境变量中
-b notify 当后台任务终止时给出通知 (在脚本中用的不多)
-c ... (none) ...读命令
-e errexit 脚本发生第一个错误时就中止脚本运行,即当一个命令返回非零值时退出脚本 (除了until 或 while loopsif-testslist constructs)
-f noglob 文件名替换停用(指像*这样的符号不能替换为文件名了)
-i interactive 使脚本以交互式方式运行
-n noexec 从脚本里读命令但不执行它们(语法检查)
-o Option-Name (none) 调用Option-Name 选项
-o posix POSIX 更改Bash或脚本的行为,使之符合POSIX标准.
-p privileged 脚本作为"suid"程序来运行 (小心!)
-r restricted 脚本在受限模式中运行 (参考第21章).
-s stdin 从标准输入读命令
-t (none) 第一个命令后就退出
-u nounset 当使用一个未定义的变量时产生一个错误信息,并强制退出脚本。
-v verbose 执行命令之前打印命令到标准输出
-x xtrace -v相似, 但打印完整的命令
- (none) 选项列表结束的标志. 后面的参数是位置参数(positional parameters).
-- (none) 释放位置参数. 如果参数列表被指定了(-- arg1 arg2), 则位置参数被依次设置为参数列表中的值.sa

三 小技巧

1.脚本可以像内嵌到另一个shell脚本的普通命令一样调用,如Tcl或wish脚本,甚至Makefile.它们可以作为外部shell命令用C语言的system()函数调用。

2.把你经常用的自定义的变量和函数放在文件中,当需要使用的时候,在脚本中使用点号.或source命令来包含这些“库文件”的一个或多个。

#mybashlib.sh

ROOT_ID=0

E_NOROOT=101

Check_is_root()

{

if [ "$UID" -ne "$ROOT_ID" ];then

echo "Must be root to run this script."

exit $E_NOROOT

fi

}

#test.sh

#!/bin/bash

. /home/zone/mybashlib.sh  #包含”库文件“,其实该句相当与执行该脚本文件

#所以”库文件“中最好不要存在一些执行性的语句,而仅仅是定义一些函数和变量。

Check_is_root  #调用函数

exit 0

3.注释代码块

(1)here文档

: <<COMMENTBLOCK

echo "This line will not echo"

=======================

echo "hello world"

=======================

COMMENTBLOCK

(2)if-test结构

#!/bin/bash

COMMENT_BLOCK=

if [ $COMMENT__BLOCK ];then

================

echo "comment"

================

fi

#通过给变量 COMMENT_BLOCK来控制注释开关

4.函数返回值给脚本,一个方法就是return num,但是num必须时0~255;另一种方法

就是让函数写值到标准输出,这种方法不仅可以返回整数,字符串,而且可以返回

多个值。

eg

#!/bin/bash

sum_and_product()

{

echo $(($1+$2)) $(($1*$2))

}

sumproduct=$(sum_and_product 10 100)

sum=$(echo "$sumproduct"|awk '{print $1}')

product=$(echo "$sumproduct"|awk '{print $2}')

exit 0

5.传递数组参数给函数,从函数返回数组

arg=$(echo "${arr[@]}"),然后把便另arg传递给函数

返回数组的时候可以用同样的方法。

posted @ 2011-03-23 10:28  xdzone  Views(1110)  Comments(0Edit  收藏  举报