English 中文(简体)
正确的Bash和shell脚本变量大写写法
原标题:
  • 时间:2009-03-23 11:34:29
  •  标签:

我发现许多 Shell 脚本中的变量都是大写字母,我一直认为这种情况存在严重误解。我的理解是,按照惯例(也许是很久以前必要的),环境变量都是大写字母。

但是在像Bash这样的现代脚本环境中,我始终更喜欢使用小写名称来表示临时变量,大写名称仅用于导出的(即环境)变量。例如:

#!/usr/bin/env bash
year=$(date +%Y)
echo "It is $year."
export JAVA_HOME="$HOME/java"

这一直是我的想法。有没有权威的来源支持或反对这种方法,还是仅仅是一种风格问题?

最佳回答

按照惯例,环境变量( PAGER EDITOR ,...)和内部shell变量( SHELL BASH_VERSION ,...)应大写。所有其他变量名称应为小写。

请记住变量名是区分大小写的;这个惯例避免了不小心覆盖环境和内部变量。

遵循这个习俗,您可以放心,不需要知道 UNIX 工具或 shell 使用的每个环境变量,以避免覆盖它们。如果它是您的变量,请使用小写字母。如果您导出它,请使用大写字母。

问题回答

任何一致遵循的命名约定都将有所帮助。以下是一些有用的Shell变量命名提示:

  • 在导出变量和常量时,请使用大写字母和下划线,特别是当它们跨多个脚本或进程共享时。 如适用,使用通用前缀,以使相关变量突出并且不会与Bash内部变量冲突,这些变量都是大写字母。

    例子:

    • Exported variables with a common prefix: JOB_HOME JOB_LOG JOB_TEMP JOB_RUN_CONTROL
    • Constants: LOG_DEBUG LOG_INFO LOG_ERROR STATUS_OK STATUS_ERROR STATUS_WARNING
  • 使用“蛇形命名法”(所有字母小写且用下划线分隔),对于在单个脚本或块范围内定义的所有变量进行命名。

    例子: input_file first_value max_amount num_errors

    当本地变量与环境变量有某种关系时,请使用混合案例,例如:old_IFS old_HOME

  • 使用领先的下划线来表示“私有”变量和函数。如果您编写了一个shell库文件,其中函数需要共享变量,在库文件或跨文件之间共享变量,而不会与主代码中可能命名相似的任何内容冲突,那么这一点尤为重要。

    例子: _debug _debug_level _current_log_file

  • 避免使用驼峰命名法。这会最小化因大小写错误而引起的错误。记住,shell变量是区分大小写的

    例子: inputArray thisLooksBAD, numRecordsProcessed, veryInconsistent_style


请参见:

如果要将 Shell 变量导出到环境中,值得考虑的是 POSIX(Issue 7,2018年版)环境变量定义 指定:

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.

I'm sorry, you did not provide any text to translate into Chinese. Please provide the text you would like translated.

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在他们经典的图书《UNIX编程环境》中,该书发行于1984年,仅讲解“shell变量”-甚至索引中都没有“环境”一词的条目!

这只是一个非常普遍的约定,我怀疑是否有任何“权威”的来源。

我倾向于在环境和全局变量中使用ALL_CAPS。 当然,在Bash中没有真正的变量作用域,因此有很多变量用作全局变量(主要是设置和状态跟踪),相对较少的是局部变量(计数器,迭代器,部分构造的字符串和临时变量)。

Bash和大多数shell脚本解释器识别函数内的全局和局部变量(例如:typeset,declare,local),应根据需要使用。如先前所述,“Shell和Utilities卷中的实用程序使用的环境变量名称仅由Portable Character Set中定义的大写字母、数字和下划线(_)组成,不以数字开头。 ...包含小写字母的环境变量名称空间保留给应用程序。应用程序可以定义任何名称空间中的环境变量名称,而不会修改标准实用程序的行为。”(POSIX IEEE Std 1003.1-2008第8.1节)

让我们在术语上清楚。环境变量是由Bash环境设置的变量(例如 ${0},${SHELL},${SECONDS} 等),不需要用户进行设置。变量(和常量)是由用户在其 .bash_profile、.bash_rc 或特定脚本文件中设置。这些变量的范围仅限于当前解释器执行(包括任何子环境的 shell 环境或执行的 shell 脚本)。如果环境变量被取消设置或重置,则通常会失去任何特殊的含义或值。

在我写 shell 脚本、执行构建和发布以及进行一些系统管理的 30 年+ 的时间里,我见过所有上述变量样式。Unix 允许由大写和小写字符或两个字符集的任何混合组成的变量名,Linux 基于可移植性出于某些未知原因采用了同样的做法。Posix 强烈鼓励使用大写字符集,几乎所有有关 Bash 编程的文本都是如此。我的结论是,这是一种广泛采用和使用的惯例,但并非严格要求,您可以自由做出任何不良选择。

话虽如此,有些约定是由于它们的实用性和帮助程序员高效地开发有用和可维护代码而被使用的。 当我编写bash代码时:

  1. 我使用大写字母和“_”符号作为所有变量和常量名称。

  2. 我使用排版来定义和初始化所有变量(和常量),并指定变量类型(整数,只读,导出,数组,哈希等),并定义变量(和常量),这些变量是函数本地变量(不是所有东西都需要在Bash中全局)。

  3. 我在所有变量周围使用{和}字符(无论语法是否需要),以避免意外的命名错误,这是我在实践中看到的。

  4. 我现在总是使用“#!/usr/bin/env bash”,以前在没有“/usr/bin/env”可用的系统上总是使用“#!/usr/bin/bash”。

  5. 我使用"shopt -s extglob #打开扩展全局表达式",因为这在我进行正则表达式时非常有用。

  6. 我总是使用 "set -o pipefail -o nounset -o errtrace -o functrace" 来避免管道在中途失败、变量名输入错误以及容易追踪错误和函数。我知道其他人经常使用 "shopt -s inherit_errexit nullglob compat",我也可以看出这些选项的实用性。

始終使用廣泛接受的慣例和良好的編程實踐可以顯著減少調試時間,使您的代碼易於移植和維護。例如,Bash不需要定義和初始化變量,但它可以防止使用未初始化的值,讓用戶編寫更好的代碼並檢測錯誤的值名稱。

我曾经为使用所有小写字母作为变量和常量的代码工作过,我的经验是这种做法使得很难清晰地看到名称的使用情况,并且容易犯错误。我在函数名称中使用驼峰命名法(个人喜好,而非约定)。这使得我清楚地知道我正在调用一个本地函数,我已经创建或引入到环境中。

最后,我建议在从另一个文件中获取代码时使用“source”命令,而不是较旧的“.”字符。如果没有其他选项,使用此选项查找我正在获取某些内容的所有位置要简单得多。

在我的职业生涯中,我学到了很多技能,远比与这个主题相关的技能多得多(是的,我已经走得很远),但Bash是*nix系统上非常有用和普遍的编程工具。通过遵循常规惯例编写清晰和可维护的代码是职业成长的标志。





相关问题
热门标签