How to write an Elegant Shell Script,怎样写一段优雅的 Shell 脚本

从一段简单的备份脚本说起, We will start from a simple backup script

这个脚本的目的是把一个 Web 目录用 tar cjf 打包,然后可以由不同的用户执行,不会有文件读写权限问题,每次打包前,要把之前的打包文件添加上日期备份好,如果打包失败,还要恢复。 The purpose of the demo script is to use “tar cjf” command to backup a web folder, different user can execute this script and will have no file permission issue. The original tarball file should be backup first to a new file name with date in the filename. In the case of failure, we will roll back the backup file.

我们会备份不同的 Web 目录,所以需要命令行传入参数,我们使用了 case 语句来判断,之所以没有用 if 是因为 if 语句会产生大量的 else 子句导致程序的可读性很差。 We will use this scrpt to backup different web folder, so the folder type is used as parameter to pass into the script. But we did not use if statement, because it will need lots “else” which will cause the script less readable. We use “case” statement to parse the “APP” name in this script.

为了记录是谁做的备份,我们需要写日志文件,而为了记录日志文件,我们写一个简单的 logger 函数,以参数传入的方式,把 logger 之后的参数 echo 显示,并添加到日志文件。 To record who and when, the user run the script, we write a function “logger”, which will need one “MSG” parameter, to echo and to append to the log file.

为了优雅的记录所有的日志,我们在日志的 MSG 前都添加了日志的 level, [debug], [info], [error], [warning] 等,我们之后如果需要分析日志,就可以简单的通过 grep 这些日志级别的关键字来查找。不同的用户可能在自己的环境会使用不同的语言设置 LC_ALL 变量,为了统一用英文,在脚本里,我们强行设置了 LC_ALL=”C”。 To record all the running log, we add log level verbosity in every MSG, e.g. [debug],[info],[error],[warning]. In case we need to find something in the log, we can just use these keywords to grep. Different user may have different language preference in their environment, to force the log file use all in English, we add LC_ALL=”C”.

为了记录所有可能的错误,我们在一些关键的执行命令后都添加了 “2>> $LOG” 这样的语句,这是为了记录可能的错误都写入到日志里。 To capture any ciritical error message, we add “2 >>$LOG” in every critial running command, so all the error log will be append to LOG file as well.

考虑到可能多人执行脚本,生成的文件权限会存在问题,我们用 umask 强制 owner 和 group 可写,同时把成功备份后的文件,强制设置为一个 同一个组 的组名。 Considered on the different user may execute the srcript, we have to make the file owner and group writeable(umask 002), and in the final step, in the success of the backup, we will change the target file’s group to a particular one, not the primary group of the executor.

OK, That’s it, let just view the whole script.

作者: 甬洁网络