SHELL程序结构化设计


本文没有高深知识,只谈shell的可读性,可理解性。我的工作中涉及到阅读一些shell程序,在阅读过程中,我发现很多所谓大牛写下来的程序没有结构,本文以举例形式来描述。

假如存在以下一些函数:函数A的功能是与读取员工信息文件(包含考勤信息和其他信息),并获取公司员工的考勤信息;函数B的功能是根据员工的考勤信息计算员工的工资;函数C、D实现其他功能。而我所看到的绝大部分脚本中的实现方式是:

#函数A,没有任何参数
A( )
{
StaffMsg=·cat StaffMsg.txt`
#解析StaffMsg.txt获取考勤信息:AttendanceMsg的代码行
echo ”$AttendanceMsg“>AttendanceMsg.txt
}

#函数B,没有任何参数
B( )
{
AttendanceMsg=`cat AttendanceMsg.txt`
       #计算工资(Wage)的代码
  echo $Wage > Wage.txt
}

#主过程,不向函数A和B传递任何参数
#*******************main*******************
#调用A函数获取员工考勤数据
A
#紧跟着有多个其他函数的调用
C
D
……
#执行函数B计算工资
B
#其他代码:
……
#删除临时文件:
rm -rf AttendanceMsg.txt
#主过程结束

       在阅读以上代码中的B函数调用时,我相信大家都会纳闷B中的msg=·cat temp_file.txt`是哪里来的,有时候不得不在脚本中Ctrl+F来搜索,好不容易才找到它是A中产生的,函数A中的StaffMsg.txt也给人一种凭空出现的感觉,最要命的是主过程中删除文件那行代码,他删除的是其他函数定义(产生)的文件,让人更是莫名其妙。这样的代码不仅难读懂,而且函数B与函数A是通过文件强耦合的,强耦合为什么不好,这个我想大家都知道(其实是我说不太清楚吐舌头);其实以上几个函数根本就不是函数,而是一些代码块,这样的设计还不如整个脚本没有函数好。那么有什么办法既能提高可读性,又能降低耦合呢,很简单:通过参数传递,模仿C++,用传入参数和传出参数,请看:
#函数A,两个参数,一个传入参数:接收员工信息,一个传出参数:输出员工考勤信息
A( )
{
StaffMsgFile=$1
AttendanceMsgFile=$2#通过传出参数来保存员工考勤信息
StaffMsg=·cat $StaffMsgFile`
#解析StaffMsg.txt获取考勤信息:AttendanceMsg的代码行
echo ”$AttendanceMsg“> $AttendanceMsgFile
}

#函数B,两个参数,一个传入参数:接收员工考勤信息,一个传出参数:输出员工工资信息
B( )
{
AttendanceMsgFile=$1
WageFile=$2
AttendanceMsg=`cat $AttendanceMsgFile`
       #计算工资(Wage)的代码
echo $Wage > $WageFile
}

#主过程,向函数A和B传递两种参数:传入参数和传出参数
#*******************main*******************
#定义员工信息文件变量和员工考勤信息文件变量
Staff_Info_File="StaffMsg.txt"
Attendance_Info_File="AttendanceMsg.txt"

#调用A函数获取员工考勤数据,并保存到变量Attendance_Info_File指示的文件中
A "$Staff_Info_File" "$Attendance_Info_File"
#紧跟着有多个其他函数的调用
C
D
……
#定义员工工资信息文件变量
Wage_File="Wage.txt"
#执行函数B计算工资,并保存结果到变量Wage_File指示的文件中
B "$Attendance_Info_File" "$Wage_File"
#其他语句
……
#删除临时文件
rm -rf $Attendance_Info_File
#主过程结束

以上代码是否是更加清晰呢?我希望你的回答是肯定的

更进一步:
我们知道在C++中,通常需要对函数参数做合法性检查,shell中通常也需要,最起码应该对参数个数做检查,这样可以避免误调用。对参数个数检查的代码可写成如下的样子:
standard_num=2
if [ $# -ne &standard_num ] ; then
echo "错误信息"
return 1
fi

相关内容