Shell 脚本最佳实践

263 阅读3分钟

这篇文章是关于我在编写 shell 脚本时使用的一些快速经验法则,多年来我逐渐领会这些法则。很有主见。

举例

  1. 使用bash。使用zshorfish或任何其他,会使其他人难以理解/协作。在所有的shell中,bash在便携性和DX之间取得了很好的平衡。

  2. 只需将第一行设为#!/usr/bin/env bash,即使您不授予脚本文件可执行权限。

  3. 为您的文件使用.sh(或.bash)扩展名。没有脚本的扩展名可能很有趣,但除非您的情况明确依赖于它,否则您可能只是想做一些聪明的事情。聪明的东西很难理解。

  4. set -o errexit在脚本的开头使用。

    • 因此,当命令失败时,bash退出而不是继续执行脚本的其余部分。
  5. 更喜欢使用set -o nounset. 你可能有很好的借口不这样做,但我认为,最好始终设置它。

    • 当访问未设置的变量时,这将使脚本失败。避免可怕的意外后果,变量名中有拼写错误。
    • 当您想要访问可能已设置或未设置的变量时,使用"${VARNAME-}"而不是"$VARNAME",就可以了。
  6. 使用set -o pipefail。同样,您可能有充分的理由不这样做,但我建议始终设置它。

    • 这将确保管道命令被视为失败,即使管道中的一个命令失败。
  7. 使用set -o xtrace, 检查$TRACE环境变量。

    • 对于复制粘贴:if [[ "${TRACE-0}" == "1" ]]; then set -o xtrace; fi
    • 这对调试脚本很有帮助。就像,真的很多。
    • 人们现在可以启用调试模式,方法是运行您的脚本TRACE=1 ./script.sh而不是./script.sh.
  8. 在/语句中使用[[ ]]for 条件,而不是or 。ifwhile[ ]test

    • [[ ]]是一个内置关键字,比[ ]or更强大test
  9. 始终用双引号引用变量访问。

    • 可以不这样做的一个地方是在条件的左侧[[ ]]。但即使在那里,我也建议引用。
    • 当您需要未引用的行为时,使用bash数组可能会更好。
  10. 在函数中使用local变量。

  11. 接受用户寻求帮助和以实物回应的多种方式。

    • 检查第一个参数是-hor --helpor helpjusth还是 even -help,在所有这些情况下,打印帮助文本并退出。
    • 为了未来的自己。
  12. 打印错误消息时,请重定向到 stderr。

    • 用于echo 'Something unexpected happened' >&2此。
  13. 尽可能使用长选项(比如--silent而不是-s)。这些用于明确记录您的命令。

    • 但请注意,在某些系统(如 macOS)上发布的命令并不总是有很长的选项。
  14. 如果合适,切换到靠近脚本开头的脚本目录。

    • 它通常总是合适的。
    • 使用cd "$(dirname "$0")",这在大多数情况下都有效。
  15. 使用shellcheck。注意它的警告。

模板

#!/usr/bin/env bash

set -o errexit
set -o nounset
set -o pipefail
if [[ "${TRACE-0}" == "1" ]]; then
    set -o xtrace
fi

if [[ "${1-}" =~ ^-*h(elp)?$ ]]; then
    echo 'Usage: ./script.sh arg-one arg-two

This is an awesome bash script to make your life better.

'
    exit
fi

cd "$(dirname "$0")"

main() {
    echo do awesome stuff
}

main "$@"

结论

我试着在我的剧本中遵循这些规则,众所周知,它们至少让我自己的生活变得更好。不幸的是,我仍然没有始终如一地遵守自己的规则。因此,也许以这种方式写下它们也能帮助我在这方面进行改进。