这是我写BASH程序的招式。这里本没有什么新的内容,但是从我的经验来看,人们爱滥用BASH。他们忽略了计算机科学,而从他们的程序中创造的是“大泥球”(译注:指架构不清晰的软件系统)。 在此我告诉你方法,以保护你的程序免于障碍,并保持代码的整洁。
不可改变的全局变量- 尽量少用全局变量
- 以大写命名
- 只读声明
- 用全局变量来代替隐晦的$0,$1等
在我的程序中常使用的全局变量:
1 2 3 | readonly PROGNAME=$( basename $0)
readonly PROGDIR=$(readlink -m $( dirname $0))
readonly ARGS= "$@"
|
一切皆是局部的所有变量都应为局部的。 1 2 3 4 5 6 7 | change_owner_of_file() {
local filename=$1
local user=$2
local group=$3
chown $user:$group $filename
}
|
1 2 3 4 5 6 7 8 9 10 11 | change_owner_of_files() {
local user=$1; shift
local group=$1; shift
local files=$@
local i
for i in $files
do
chown $user:$group $i
done
}
|
- 自注释(self documenting)的参数
- 通常作为循环用的变量i,把它声明为局部变量是很重要的。
- 局部变量不作用于全局域。
1 2 | kfir@goofy ~ $ local a
bash : local : can only be used in a function
|
main()- 有助于保持所有变量的局部性
- 直观的函数式编程
代码中唯一的全局命令是:main
1 2 3 4 5 6 7 8 9 10 | main() {
local files= "/tmp/a /tmp/b"
local i
for i in $files
do
change_owner_of_file kfir users $i
done
}
main
|
一切皆是函数- 不可变的全局变量声明 - main()函数 1 2 3 | main() {
local files=$( ls /tmp | grep pid | grep - v daemon)
}
|
1 2 3 4 5 6 7 8 9 10 11 | temporary_files() {
local dir =$1
ls $ dir \
| grep pid \
| grep - v daemon
}
main() {
local files=$(temporary_files /tmp )
}
|
1 2 3 4 5 6 7 8 9 10 11 12 | test_temporary_files() {
local dir = /tmp
touch $ dir /a-pid1232 .tmp
touch $ dir /a-pid1232-daemon .tmp
returns "$dir/a-pid1232.tmp" temporary_files $ dir
touch $ dir /b-pid1534 .tmp
returns "$dir/a-pid1232.tmp $dir/b-pid1534.tmp" temporary_files $ dir
}
|
如你所见,这个测试不关心main()。 调试函数只调试一小段代码,使用set-x和set+x,会只对被set -x和set +x包含的当前代码打印调试信息。 1 2 3 4 5 6 7 8 9 | temporary_files() {
local dir =$1
set -x
ls $ dir \
| grep pid \
| grep - v daemon
set +x
}
|
打印函数名和它的参数: 1 2 3 4 5 6 7 8 | temporary_files() {
echo $FUNCNAME $@
local dir =$1
ls $ dir \
| grep pid \
| grep - v daemon
}
|
调用函数: 会打印到标准输出:
|