任何准备发布到公开环境的代码,都应该包含以下短头部:
在代码头部保持变更日志是版本控制系统非常不方便的时代遗留下来的一种做法。最后修改日期显示了脚本的年龄。
如果您要依赖于bashism,请使用#!/bin/bash而不是/bin/sh,因为sh是任何shell的POSIX调用方式。即使/bin/sh指向bash,如果通过/bin/sh运行它,许多功能也将被关闭。大多数Linux发行版都不会接受依赖于bashism的脚本,请尽量做到可移植性。
当涉及到继承他人的脚本时,我发现人们往往在不需要注释的地方进行大量注释(例如#循环$var)并且在需要注释的地方(例如超长Perl one-liner或具有几十个参数的JVM执行)却很零散。这在很多已经建立的代码库中都是一个问题,但在脚本中尤其令人沮丧。我不知道/bin/foo -- {mile long list of arguments}通过查看它可以做什么,但我确实知道如何编写脚本构造。在你正在做一些表面上看起来有点疯狂的事情时,评论也会非常受欢迎。
有些Shell不喜欢输入类型为“local”的变量。我认为直到今天,Busybox(常用的救援Shell之一)仍然是这种情况。因此,使用明显的全局变量名称更容易阅读,特别是在通过/bin/sh -x ./script.sh进行调试时。
我个人倾向于让逻辑自己说话,并尽量减少解析器的工作量。例如,很多人可能会写:
if [ $i = 1 ]; then
... some code
fi
我会这样做:
[ $i = 1 ] && {
... some code
}
同样的,有人可能会写:
if [ $i -ne 1 ]; then
... some code
fi
... 我想要的是:
[ $i = 1 ] || {
... some code
}
只有当存在 else-if 的情况下,我才会使用传统的 if / then / else。
在大多数使用 autoconf 的免费软件包的“configure”脚本中,可以学习到一种非常好的可移植 shell 代码的可怕且疯狂的示例。我说是疯狂的,因为它有 6300 行代码,适用于所有已知的具有类 UNIX shell 的人类系统。你不需要那种膨胀的东西,但是研究其中的各种可移植性黑客技巧还是很有趣的,比如对那些可能把 /bin/sh 指向 zsh 的人友善起来:)
我唯一能给出的其他建议就是要注意这里文档的扩展,即:
cat << EOF > foo.sh
printf "%s was here" "$name"
EOF
...将扩展$name, 但你可能希望保持变量不变。通过以下方式解决:
printf "%s was here" "\$name"
使用单引号将$name作为变量而不是展开它,是一个很好的习惯。
我也强烈建议学习如何使用trap捕获信号,并将这些处理程序用作样板代码。使用简单的SIGUSR1告诉运行中的脚本减速是非常方便的 :)
我写的大多数新程序(面向工具/命令行)都以shell脚本开始,这是原型制作UNIX工具的好方法。
您可能还喜欢SHC shell脚本编译器,请在此处查看。
__
前缀是有益的。 - Jonathan Leffler