更正Bash和shell脚本变量大小写

Correct Bash and shell script variable capitalization

我遇到了许多shell脚本,其中的变量都是大写的,我一直认为这是一个严重的误解。我的理解是,按照惯例(也许很久以前就有必要),环境变量都是有上限的。

但是在现代脚本环境(如bash)中,我总是倾向于使用小写字母作为临时变量,而大写字母仅用于导出(即环境)变量。例如:

1
2
3
4
#!/usr/bin/env bash
year=`date +%Y`
echo"It is $year."
export JAVA_HOME="$HOME/java"

这一直是我对事情的看法。是否有权威人士同意或不同意这种方法,或者这纯粹是一种风格问题?


按照惯例,环境变量(PAGEREDITOR…)和内部外壳变量(SHELLBASH_VERSION…)都是大写的。所有其他变量名都应为小写。

记住变量名区分大小写;此约定避免意外地覆盖环境变量和内部变量。

按照这个惯例,您可以放心,您不需要知道Unix工具或shell使用的每个环境变量,以避免覆盖它们。如果是你的变量,用小写。如果导出,则大写。


任何一贯遵循的命名约定都会有所帮助。以下是一些关于shell变量命名的有用提示:

  • 为导出的变量和常量使用所有的大写和下划线,尤其是在跨多个脚本或进程共享这些变量和常量时。在适当的时候使用一个公共前缀,这样相关的变量就会突出,并且不会与所有大写的bash内部变量发生冲突。

    实例:

    • 带公共前缀的导出变量:JOB_HOMEJOB_LOGJOB_TEMPJOB_RUN_CONTROL
    • 常数:LOG_DEBUGLOG_INFOLOG_ERRORSTATUS_OKSTATUS_ERRORSTATUS_WARNING
  • 对于范围为单个脚本或块的所有变量,使用"snake case"(所有小写和下划线)。

    示例:input_filefirst_valuemax_amountnum_errors

    局部变量与环境变量有一定关系时的混合情况,如:old_IFSold_HOME

  • 对"private"变量和函数使用前导下划线。如果编写一个shell库,其中库文件内或跨文件的函数需要共享变量,而不会与主代码中类似命名的任何内容发生冲突,那么这一点尤其重要。

    示例:_debug_debug_level_current_log_file

  • 避免驼色箱子。这将最小化由大小写错误引起的错误。记住,shell变量区分大小写。

    示例:inputArraythisLooksBADnumRecordsProcessedveryInconsistent_style

参见:

  • 开放组基本规范第7期-环境变量


我做你做的。我怀疑有权威的来源,但它似乎是一个相当广泛的事实标准。


如果要将shell变量导出到环境中,那么值得考虑的是,posix(2018年第7期)环境变量定义指定了:

Environment variable names used by the utilities in the Shell and Utilities
volume of POSIX.1-2017 consist solely of uppercase letters, digits, and the
underscore ( _ ) from the characters defined in Portable Character Set
and do not begin with a digit.

The name space of environment variable names containing lowercase letters is
reserved for applications. Applications can define any environment variables
with names from this name space without modifying the behavior of the
standard utilities.


实际上,"环境变量"这个词似乎是最近才出现的。Kernighan和Pike在1984年出版的经典著作《Unix编程环境》中只提到了"shell变量"—索引中甚至没有"environment"的条目!


这只是一个非常广泛持有的公约,我怀疑是否有任何"权威"的来源。


我倾向于对环境和全局变量都使用大写。当然,在bash中没有真正的变量范围,所以有相当一部分变量用作全局变量(主要是设置和状态跟踪),相对较少的"局部变量"(计数器、迭代器、部分构造的字符串和临时变量)。