By convention, environment variables (PAGER, EDITOR, ...) and internal shell variables (SHELL, BASH_VERSION, ...) are capitalized. All other variable names should be lower case.
Remember that variable names are case-sensitive; this convention avoids accidentally overriding environmental and internal variables.
Keeping to this convention, you can rest assured that you don't need to know every environment variable used by UNIX tools or shells in order to avoid overwriting them. If it's your variable, lowercase it. If you export it, uppercase it.
Any naming conventions followed consistently will always help. Here are a few helpful tips for shell variable naming:
Use all caps and underscores for exported variables and constants, especially when they are shared across multiple scripts or processes. Use a common prefix whenever applicable so that related variables stand out and won't clash with Bash internal variables which are all upper case.
Examples:
Exported variables with a common prefix: JOB_HOMEJOB_LOGJOB_TEMPJOB_RUN_CONTROL
Use mixed case when local variable has some relationship with an environment variable, like: old_IFSold_HOME
Use a leading underscore for "private" variables and functions. This is especially relevant if you ever write a shell library where functions within a library file or across files need to share variables, without ever clashing with anything that might be similarly named in the main code.
Examples: _debug_debug_level_current_log_file
Avoid camel case. This will minimize the bugs caused by case typos. Remember, shell variables are case sensitive.
If shell variables are going to be exported to the environment, it’s worth considering that the POSIX (Issue 7, 2018 edition) Environment Variable Definition specifies:
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.
Actually, the term "environment variables" seems to be of fairly recent coinage. Kernighan and Pike in their classic book "The UNIX Programming Environment", published in 1984, speak only of "shell variables" - there is not even an entry for "environment" in the index!
Let's be clear on our terminology. Environment variables are those variables set by the Bash environment (e.g. ${0}, ${SHELL}, ${SECONDS}, etc.) and which do not need to be set by the user. User Variables (and Constants) are set by the user either in their .bash_profile, .bash_rc, or in a particular script file. User variables can be exported to the environment to become Environment variables; however, unless exported, the scope of User variable is limited to the current interpreter execution (either the shell environment or the executing shell script [i.e. will not be passed to any child] environment). If an Environment variable is unset, or reset, it will usually lose any special meaning or value.
In my 30+ years writing shell scripts, doing Build and Release and some System Administration, I've seen all of the aforementioned variable styles. Unix allows variable names composed of the majuscule and minuscule characters or any mix of the two sets, Linux adopted this same abomination for some unknown reason, probably portability. Posix strongly encourages the use of the majuscule character set as do almost all texts on Bash programming. My conclusion is that this is a convention that is widely adopted and used, but is not strictly required and you are free to make any poor choice you wish.
That said, there are some conventions that are used because of their utility and because they help programmers efficiently and effectively develop useful and maintainable code. When I write bash code:
I use majuscule characters and the '_' characters for all variable and constant names.
I typeset (AKA define) and initialize all variables (and constants) and specify the variable type (integer, read only, exported, array, hash, etc.) that are local to scripts and functions (no everything does not need to be global in Bash).
I use '{' and '}' characters around all variables (syntactically required or not, to avoid unintentional naming errors, which I have seen in practice) and makes the Variable/Constant stand out.
I always use "#!/usr/bin/env bash" now, and previously always used "#!/usr/bin/bash" on systems where "/usr/bin/env" was not available.
I use "shopt -s extglob # Turn on extended global expressions" in my scripts because this is great to have when I'm doing regular expressions and pattern matching.
I always use "set -o pipefail -o nounset -o errtrace -o functrace" to avoid issues with pipes failing in the middle, fat fingering variable names, and ease of tracing errors and functions. I know of others that often use " shopt -s inherit_errexit nullglob compat" and I can see the utility of these options as well.
All error messages I print out follow a pattern that will let the programmer know where in the code the error was found and reported. echo -e "ERROR [${LINENO}] in ${FUNCNAME[*]}: ..." 1>&2
Consistently using widely accepted conventions and good programming practices can significantly reduce debug time and make your code easily portable and maintainable. For example, Bash doesn't require defining and initializing variables, but it can prevent using uninitialised values and lets users write better code and detect mispelled value names.
Having worked on code that uses all miniscule characters for variables and constants, my experience is that this practice makes it very difficult to clearly see where the variable is being used, and makes it very easy to make mistakes.
I use camel case naming in function names (personal preference, not convention). This makes it clear that I am calling a local function which I've created or sourced into the environment.
Lastly, I recommend using the "source" command, in place of the older '.' character when sourcing in code from another file. If nothing else, finding all the places where I'm sourcing something is much easier with this option.
There are a lot of skills I've learned in my career, far more than are relevant to this topic (yes, I've wandered far afield), but Bash is an incredibly useful and ubiquitous programming tool on *nix systems. Learning to write clear and maintainable code by following the common conventions is a mark of professional growth.
i tend use ALL_CAPS both for environment and global variables. of course, in Bash there's no real variable scope, so there's a good portion of variables used as globals (mostly settings and state tracking), and relatively few 'locals' (counters, iterators, partly-constructed strings, and temporaries)
Bash, and most shell script interpreters, recognize global and local variables within functions (e.g typeset, declare, local) and should be used as appropriate. As previously commented, "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." (POSIX IEEE Std 1003.1-2008 section 8.1 )
发布评论
评论(9)
按照惯例,环境变量(
PAGER
、EDITOR
、...)和内部 shell 变量(SHELL
、BASH_VERSION
) , ...) 均大写。 所有其他变量名称都应小写。请记住,变量名称区分大小写; 此约定可避免意外覆盖环境变量和内部变量。
遵循此约定,您可以放心,您不需要了解 UNIX 工具或 shell 使用的每个环境变量以避免覆盖它们。 如果它是您的变量,请将其小写。 如果导出,请将其大写。
By convention, environment variables (
PAGER
,EDITOR
, ...) and internal shell variables (SHELL
,BASH_VERSION
, ...) are capitalized. All other variable names should be lower case.Remember that variable names are case-sensitive; this convention avoids accidentally overriding environmental and internal variables.
Keeping to this convention, you can rest assured that you don't need to know every environment variable used by UNIX tools or shells in order to avoid overwriting them. If it's your variable, lowercase it. If you export it, uppercase it.
任何一致遵循的命名约定总是有帮助的。 以下是有关 shell 变量命名的一些有用提示:
对导出的变量和常量使用全部大写和下划线,尤其是当它们在多个脚本或进程之间共享时。 只要适用,请使用通用前缀,以便相关变量脱颖而出,并且不会与 Bash 内部变量 全部大写。
示例:
JOB_HOME
JOB_LOG
JOB_TEMP
JOB_RUN_CONTROL
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
、veryInconcient_style
另请参阅:
Any naming conventions followed consistently will always help. Here are a few helpful tips for shell variable naming:
Use all caps and underscores for exported variables and constants, especially when they are shared across multiple scripts or processes. Use a common prefix whenever applicable so that related variables stand out and won't clash with Bash internal variables which are all upper case.
Examples:
JOB_HOME
JOB_LOG
JOB_TEMP
JOB_RUN_CONTROL
LOG_DEBUG
LOG_INFO
LOG_ERROR
STATUS_OK
STATUS_ERROR
STATUS_WARNING
Use "snake case" (all lowercase and underscores) for all variables that are scoped to a single script or a block.
Examples:
input_file
first_value
max_amount
num_errors
Use mixed case when local variable has some relationship with an environment variable, like:
old_IFS
old_HOME
Use a leading underscore for "private" variables and functions. This is especially relevant if you ever write a shell library where functions within a library file or across files need to share variables, without ever clashing with anything that might be similarly named in the main code.
Examples:
_debug
_debug_level
_current_log_file
Avoid camel case. This will minimize the bugs caused by case typos. Remember, shell variables are case sensitive.
Examples:
inputArray
thisLooksBAD
,numRecordsProcessed
,veryInconsistent_style
See also:
如果要将 shell 变量导出到环境中,则值得考虑 POSIX(2018 年第 7 期版)环境变量定义指定:
...
If shell variables are going to be exported to the environment, it’s worth considering that the POSIX (Issue 7, 2018 edition) Environment Variable Definition specifies:
...
我做你做的事。 我怀疑是否有权威来源,但这似乎是一个相当广泛的事实上的标准。
I do what you do. I doubt there's an authoritative source, but it seems a fairly widespread de-facto standard.
实际上,“环境变量”这个术语似乎是最近才创造的。 Kernighan 和 Pike 在 1984 年出版的经典著作《UNIX 编程环境》中只提到了“shell 变量”——索引中甚至没有“环境”条目!
Actually, the term "environment variables" seems to be of fairly recent coinage. Kernighan and Pike in their classic book "The UNIX Programming Environment", published in 1984, speak only of "shell variables" - there is not even an entry for "environment" in the index!
让我们澄清一下我们的术语。 环境变量是由 Bash 环境设置的变量(例如 ${0}、${SHELL}、${SECONDS} 等),不需要用户设置。 用户变量(和常量)由用户在其 .bash_profile、.bash_rc 或特定脚本文件中设置。 用户变量可以导出到环境中成为环境变量; 但是,除非导出,否则 User 变量的范围仅限于当前解释器执行(shell 环境或正在执行的 shell 脚本[即不会传递到任何子]环境)。 如果环境变量被取消设置或重置,它通常会失去任何特殊含义或值。
在我编写 shell 脚本、构建和发布以及一些系统管理的 30 多年中,我见过所有上述变量样式。 Unix 允许变量名由大写字符和小写字符组成,或者两者的任意组合,Linux 由于某种未知的原因(可能是可移植性)采用了同样令人厌恶的做法。 Posix 强烈鼓励使用大字符集,就像几乎所有有关 Bash 编程的文本一样。 我的结论是,这是一个被广泛采用和使用的约定,但并不是严格要求的,您可以自由地做出任何您希望的糟糕选择。
也就是说,有一些约定因其实用性而被使用,因为它们可以帮助程序员高效且有效地开发有用且可维护的代码。 当我编写 bash 代码时:
我对所有变量和常量名称使用大字符和“_”字符。
我排版(又名定义)并初始化所有变量(和常量),并指定脚本和函数本地的变量类型(整数、只读、导出、数组、散列等)(不是所有东西都不需要在 Bash 中实现全局)。
我在所有变量周围使用“{”和“}”字符(语法上是否必需,以避免无意的命名错误,我在实践中见过这种情况)并使变量/常量脱颖而出。
我现在总是使用“#!/usr/bin/env bash”,以前总是在“/usr/bin/env”不可用的系统上使用“#!/usr/bin/bash”。
我在脚本中使用“shopt -s extglob # 打开扩展全局表达式”,因为当我进行正则表达式和模式匹配时,这非常有用。
我总是使用“set -o pipelinefail -o nounset -o errtrace -o functrace”来避免管道在中间失败、错误指法变量名称以及轻松跟踪错误和函数的问题。 我知道其他人经常使用“shopt -s Heritage_errexit nullglob compat”,我也可以看到这些选项的实用性。
我打印出的所有错误消息都遵循一种模式,该模式将使程序员知道在代码中的何处发现并报告了错误。
echo -e "${FUNCNAME[*]} 中的错误 [${LINENO}]: ..." 1>&2
一致使用广泛接受的约定和良好的编程实践可以显着减少调试时间并使您的代码易于移植和可维护。 例如,Bash 不需要定义和初始化变量,但它可以防止使用未初始化的值,并允许用户编写更好的代码并检测拼写错误的值名称。
在编写使用所有微小字符作为变量和常量的代码后,我的经验是,这种做法使得很难清楚地看到变量的使用位置,并且很容易出错。
我在函数名称中使用驼峰式命名(个人喜好,而不是惯例)。 这清楚地表明我正在调用我在环境中创建或获取的本地函数。
最后,我建议使用“source”命令来代替旧的“.”命令。 从另一个文件获取代码时的字符。 如果不出意外的话,使用此选项可以更轻松地找到我采购商品的所有地点。
我在职业生涯中学到了很多技能,远远超出了与本主题相关的技能(是的,我已经走得很远了),但 Bash 是 *nix 系统上非常有用且无处不在的编程工具。 学习遵循通用约定来编写清晰且可维护的代码是专业成长的标志。
Let's be clear on our terminology. Environment variables are those variables set by the Bash environment (e.g. ${0}, ${SHELL}, ${SECONDS}, etc.) and which do not need to be set by the user. User Variables (and Constants) are set by the user either in their .bash_profile, .bash_rc, or in a particular script file. User variables can be exported to the environment to become Environment variables; however, unless exported, the scope of User variable is limited to the current interpreter execution (either the shell environment or the executing shell script [i.e. will not be passed to any child] environment). If an Environment variable is unset, or reset, it will usually lose any special meaning or value.
In my 30+ years writing shell scripts, doing Build and Release and some System Administration, I've seen all of the aforementioned variable styles. Unix allows variable names composed of the majuscule and minuscule characters or any mix of the two sets, Linux adopted this same abomination for some unknown reason, probably portability. Posix strongly encourages the use of the majuscule character set as do almost all texts on Bash programming. My conclusion is that this is a convention that is widely adopted and used, but is not strictly required and you are free to make any poor choice you wish.
That said, there are some conventions that are used because of their utility and because they help programmers efficiently and effectively develop useful and maintainable code. When I write bash code:
I use majuscule characters and the '_' characters for all variable and constant names.
I typeset (AKA define) and initialize all variables (and constants) and specify the variable type (integer, read only, exported, array, hash, etc.) that are local to scripts and functions (no everything does not need to be global in Bash).
I use '{' and '}' characters around all variables (syntactically required or not, to avoid unintentional naming errors, which I have seen in practice) and makes the Variable/Constant stand out.
I always use "#!/usr/bin/env bash" now, and previously always used "#!/usr/bin/bash" on systems where "/usr/bin/env" was not available.
I use "shopt -s extglob # Turn on extended global expressions" in my scripts because this is great to have when I'm doing regular expressions and pattern matching.
I always use "set -o pipefail -o nounset -o errtrace -o functrace" to avoid issues with pipes failing in the middle, fat fingering variable names, and ease of tracing errors and functions. I know of others that often use " shopt -s inherit_errexit nullglob compat" and I can see the utility of these options as well.
All error messages I print out follow a pattern that will let the programmer know where in the code the error was found and reported.
echo -e "ERROR [${LINENO}] in ${FUNCNAME[*]}: ..." 1>&2
Consistently using widely accepted conventions and good programming practices can significantly reduce debug time and make your code easily portable and maintainable. For example, Bash doesn't require defining and initializing variables, but it can prevent using uninitialised values and lets users write better code and detect mispelled value names.
Having worked on code that uses all miniscule characters for variables and constants, my experience is that this practice makes it very difficult to clearly see where the variable is being used, and makes it very easy to make mistakes.
I use camel case naming in function names (personal preference, not convention). This makes it clear that I am calling a local function which I've created or sourced into the environment.
Lastly, I recommend using the "source" command, in place of the older '.' character when sourcing in code from another file. If nothing else, finding all the places where I'm sourcing something is much easier with this option.
There are a lot of skills I've learned in my career, far more than are relevant to this topic (yes, I've wandered far afield), but Bash is an incredibly useful and ubiquitous programming tool on *nix systems. Learning to write clear and maintainable code by following the common conventions is a mark of professional growth.
我倾向于使用 ALL_CAPS 来表示环境变量和全局变量。 当然,在 Bash 中没有真正的变量作用域,因此有很大一部分变量用作全局变量(主要是设置和状态跟踪),而“局部变量”相对较少(计数器、迭代器、部分构造的字符串和临时变量)
i tend use ALL_CAPS both for environment and global variables. of course, in Bash there's no real variable scope, so there's a good portion of variables used as globals (mostly settings and state tracking), and relatively few 'locals' (counters, iterators, partly-constructed strings, and temporaries)
这只是一个非常广泛举行的会议,我怀疑它是否有任何“权威”来源。
It's just a very widely held convention, I doubt there's any "authoritative" source for it.
Bash 和大多数 shell 脚本解释器都可以识别函数中的全局变量和局部变量(例如排版、声明、本地),并且应该适当地使用。 如前所述,“POSIX.1-2017 的 Shell 和实用程序卷中的实用程序使用的环境变量名称仅由可移植字符集中定义的字符中的大写字母、数字和下划线 ( _ ) 组成,并且不开头包含小写字母的环境变量名称的名称空间是为应用程序保留的,应用程序可以使用此名称空间中的名称定义任何环境变量,而无需修改标准实用程序的行为。 (POSIX IEEE Std 1003.1-2008 第 8.1 节)
Bash, and most shell script interpreters, recognize global and local variables within functions (e.g typeset, declare, local) and should be used as appropriate. As previously commented, "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." (POSIX IEEE Std 1003.1-2008 section 8.1 )