就目前的情况而言,此问题不适合我们的问答格式。我们希望答案能得到事实、参考资料或专业知识的支持,但此问题可能会引发辩论、争论、民意调查或广泛讨论。如果您认为此问题可以改进并可能重新讨论,请访问visit the help center以获取指导。
10年前关闭了。
有人知道有什么资源讨论shell脚本(sh、bash等)的最佳实践或设计模式吗?
就目前的情况而言,此问题不适合我们的问答格式。我们希望答案能得到事实、参考资料或专业知识的支持,但此问题可能会引发辩论、争论、民意调查或广泛讨论。如果您认为此问题可以改进并可能重新讨论,请访问visit the help center以获取指导。
10年前关闭了。
有人知道有什么资源讨论shell脚本(sh、bash等)的最佳实践或设计模式吗?
8条答案
按热度按时间83qze16e1#
我写过相当复杂的shell脚本,我的第一个建议是"不要",原因是很容易犯一个小错误,阻碍你的脚本,甚至使它变得危险。
也就是说,除了我的个人经历,我没有其他的资源可以传递给你。下面是我通常做的,这是矫枉过正,但往往是坚实的,虽然 * 非常 * 冗长。
让你的脚本接受long和short选项。2要小心,因为有两个命令可以解析选项,getopt和getopts。3使用getopt你会遇到更少的麻烦。
另一个要点是,如果程序成功完成,它应该总是返回零,如果出错,它应该总是返回非零。
你可以在bash中调用函数,只要记住在调用之前定义它们。函数就像脚本,它们只能返回数值。这意味着你必须发明一种不同的策略来返回字符串值。我的策略是使用一个名为RESULT的变量来存储结果,如果函数干净地完成,则返回0。同样,如果返回的值不为零,则可以引发异常。然后设置两个"异常变量"(我的:EXCEPTION和EXCEPTION_MSG),第一个包含异常类型,第二个包含人类可读消息。
当你调用一个函数时,函数的参数会被赋值给特殊的变量$0,$1等。我建议你把它们命名为更有意义的名字。声明函数中的变量为局部变量:
在bash中,除非声明为空字符串,否则unset变量将被用作空字符串。这在输入错误的情况下是非常危险的,因为错误类型的变量将不会被报告,并且它将被计算为空。use
以防止这种情况发生。但是要小心,因为如果你这样做,程序将在你每次计算一个未定义的变量时中止。因此,检查变量是否未定义的唯一方法如下:
可以将变量声明为只读:
如果使用以下代码,就可以实现"类似Python"的模块化:
然后,可以使用以下语法导入扩展名为. shinc的文件
导入"A模块/模块文件"
它将在SHELL_LIBRARY_PATH中搜索。由于您总是在全局名称空间中导入,请记住为所有函数和变量添加适当的前缀,否则可能会出现名称冲突。我使用双下划线作为python点。
此外,将此作为模块中的第一项内容
在bash中,你不能进行面向对象的编程,除非你构建了一个相当复杂的对象分配系统(我考虑过了,这是可行的,但很疯狂)。每个对象都有一个示例,而且只有一个。
我做的是:我在模块中定义了一个对象(参见模块化条目),然后定义了空变量(类似于成员变量)、init函数(构造函数)和成员函数,如下面的示例代码所示
我发现这对于捕获和处理异常非常有用。
如果由于某种原因有些东西不起作用,试着重新排序代码。顺序很重要,但并不总是直观的。
甚至不要考虑使用tcsh。它不支持函数,而且总的来说很糟糕。
请注意:如果你不得不使用我在这里写的那种东西,那就意味着你的问题太复杂了,不能用shell来解决。使用另一种语言。由于人为因素和遗留问题,我不得不使用它。
pxy2qtax2#
看一看Advanced Bash-Scripting Guide,了解关于shell脚本的许多智慧a-不仅仅是Bash。
不要听别人的建议,看看其他更复杂的语言。如果shell脚本能满足你的需求,就用它吧。你需要的是功能,而不是花哨。新语言为你的简历提供了有价值的新技能,但如果你有工作要做,而你已经知道shell,那就没有帮助了。
如前所述,shell脚本没有太多的“最佳实践”或“设计模式”,不同的用途有不同的指导方针和偏见--就像任何其他编程语言一样。
anhgbhbe3#
shell脚本是一种设计用来操作文件和进程的语言。虽然它非常适合于此,但它不是一种通用语言,所以总是尝试从现有实用程序中粘贴逻辑,而不是在shell脚本中重新创建新逻辑。
除了这个一般原则,我还收集了一些common shell script mistakes。
omjgkv6w4#
知道什么时候使用它。对于快速和肮脏的粘合命令在一起是可以的。如果你需要做一些重要的决定,循环,任何事情,去Python,Perl,和模块化。
shell最大的问题通常是最终结果看起来像一个大泥球,4000行bash和增长...你不能摆脱它,因为现在你的整个项目都依赖于它。当然,它开始于40行漂亮的bash。
cngwdvgl5#
今年(2008年)在OSCON就这个主题举行了一次很棒的会议:http://assets.en.oreilly.com/1/event/12/Shell%20Scripting%20Craftsmanship%20Presentation%201.pdf
irtuqstp6#
使用set -e,这样你就不会在错误之后继续前进。如果你想让它在非Linux上运行,尝试让它与sh兼容,而不依赖bash。
jq6vz3qz7#
简单:用python代替shell脚本,你的可读性提高了近100倍,不需要复杂化任何你不需要的东西,并且几乎不需要任何额外的代码就可以把你的脚本的一部分发展成函数、对象、持久对象(zodb)、分布式对象(pyro)。
slmsl1lt8#
要找到一些“最佳实践”,请查看Linux发行版(例如Debian)是如何编写其init脚本的(通常在/etc/init.d中找到)
它们中的大多数都没有“bash-isms”,并且很好地分离了配置设置、库文件和源格式。
我个人的风格是编写一个定义了一些默认变量的master-shellscript,然后尝试加载(“源”)一个可能包含新值的配置文件。
我尽量避免使用函数,因为它们往往会使脚本更加复杂(Perl就是为此而创建的)。
要确保脚本是可移植的,不仅要使用#!/bin/sh进行测试,还要使用#!/bin/ash、#!/bin/dash等。您很快就会发现特定于Bash的代码。