From 8e2dc76c1b954830279d23e7ae6a457f85415479 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Thu, 16 Jan 2025 18:31:48 -0500 Subject: [PATCH] shell: Project import generated by Copybara. PiperOrigin-RevId: 716401731 --- shellguide.md | 133 +++++++++++++++++++++++--------------------------- 1 file changed, 61 insertions(+), 72 deletions(-) diff --git a/shellguide.md b/shellguide.md index d18805e..86f6920 100644 --- a/shellguide.md +++ b/shellguide.md @@ -7,14 +7,6 @@ See README.md for details. # Shell Style Guide - - -Revision 2.02 - Authored, revised and maintained by many Googlers. ## Table of Contents @@ -69,18 +61,16 @@ used for widespread deployment. Some guidelines: -* If you're mostly calling other utilities and are doing relatively - little data manipulation, shell is an acceptable choice for the task. +* If you're mostly calling other utilities and are doing relatively little + data manipulation, shell is an acceptable choice for the task. * If performance matters, use something other than shell. -* If you are writing a script that is more than 100 lines long, or - that uses non-straightforward control flow logic, you should - rewrite it in a more structured language *now*. Bear in - mind that scripts grow. Rewrite your script early to avoid a more - time-consuming rewrite at a later date. -* When assessing the complexity of your code (e.g. to decide whether - to switch languages) consider whether the code is easily - maintainable by people other than its author. - +* If you are writing a script that is more than 100 lines long, or that uses + non-straightforward control flow logic, you should rewrite it in a more + structured language *now*. Bear in mind that scripts grow. Rewrite your + script early to avoid a more time-consuming rewrite at a later date. +* When assessing the complexity of your code (e.g. to decide whether to switch + languages) consider whether the code is easily maintainable by people other + than its author. @@ -90,19 +80,21 @@ Some guidelines: ### File Extensions -Executables should have no extension (strongly preferred) or a -`.sh` extension. Libraries must have a `.sh` -extension and should not be executable. +Executables should have a `.sh` extension or no extension. -It is not necessary to know what language a program is written in when -executing it and shell doesn't require an extension so we prefer not -to use one for executables. +- If the executable will have a build rule that renames the source file + then prefer to use a `.sh` extension. + This enables you to use the recommended naming convention, with a source + file like `foo.sh` and a build rule named `foo`. +- If the executable will be added directly to the user's `PATH`, then prefer + to use no extension. It is not necessary to know what language a program is + written in when executing it and shell doesn't require an extension so we + prefer not to use one for executables that will be directly invoked by + users. At the same time, consider whether it is preferable to deploy the + output of a build rule rather than deploying the source file directly. +- If neither of the above apply, then either choice is acceptable. -However, for libraries it's important to know what language it is and -sometimes there's a need to have similar libraries in different -languages. This allows library files with identical purposes but -different languages to be identically named except for the -language-specific suffix. +Libraries must have a `.sh` extension and should not be executable. @@ -184,8 +176,8 @@ All function header comments should describe the intended API behaviour using: * Globals: List of global variables used and modified. * Arguments: Arguments taken. * Outputs: Output to STDOUT or STDERR. -* Returns: Returned values other than the default exit status of the - last command run. +* Returns: Returned values other than the default exit status of the last + command run. Example: @@ -406,11 +398,10 @@ done ### Case statement * Indent alternatives by 2 spaces. -* A one-line alternative needs a space after the close parenthesis of - the pattern and before the `;;`. -* Long or multi-command alternatives should be split over multiple - lines with the pattern, actions, and `;;` on separate - lines. +* A one-line alternative needs a space after the close parenthesis of the + pattern and before the `;;`. +* Long or multi-command alternatives should be split over multiple lines with + the pattern, actions, and `;;` on separate lines. The matching expressions are indented one level from the `case` and `esac`. Multiline actions are indented another level. In general, there is no need to @@ -475,42 +466,42 @@ They are listed in order of precedence. * Don't brace-delimit single character shell specials / positional parameters, unless strictly necessary or avoiding deep confusion. - Prefer brace-delimiting all other variables. +Prefer brace-delimiting all other variables. - ```shell - # Section of *recommended* cases. +```shell +# Section of *recommended* cases. - # Preferred style for 'special' variables: - echo "Positional: $1" "$5" "$3" - echo "Specials: !=$!, -=$-, _=$_. ?=$?, #=$# *=$* @=$@ \$=$$ …" +# Preferred style for 'special' variables: +echo "Positional: $1" "$5" "$3" +echo "Specials: !=$!, -=$-, _=$_. ?=$?, #=$# *=$* @=$@ \$=$$ …" - # Braces necessary: - echo "many parameters: ${10}" +# Braces necessary: +echo "many parameters: ${10}" - # Braces avoiding confusion: - # Output is "a0b0c0" - set -- a b c - echo "${1}0${2}0${3}0" +# Braces avoiding confusion: +# Output is "a0b0c0" +set -- a b c +echo "${1}0${2}0${3}0" - # Preferred style for other variables: - echo "PATH=${PATH}, PWD=${PWD}, mine=${some_var}" - while read -r f; do - echo "file=${f}" - done < <(find /tmp) - ``` +# Preferred style for other variables: +echo "PATH=${PATH}, PWD=${PWD}, mine=${some_var}" +while read -r f; do + echo "file=${f}" +done < <(find /tmp) +``` - ```shell - # Section of *discouraged* cases +```shell +# Section of *discouraged* cases - # Unquoted vars, unbraced vars, brace-delimited single letter - # shell specials. - echo a=$avar "b=$bvar" "PID=${$}" "${1}" +# Unquoted vars, unbraced vars, brace-delimited single letter +# shell specials. +echo a=$avar "b=$bvar" "PID=${$}" "${1}" - # Confusing use: this is expanded as "${1}0${2}0${3}0", - # not "${10}${20}${30} - set -- a b c - echo "$10$20$30" - ``` +# Confusing use: this is expanded as "${1}0${2}0${3}0", +# not "${10}${20}${30} +set -- a b c +echo "$10$20$30" +``` NOTE: Using braces in `${var}` is *not* a form of quoting. "Double quotes" must be used *as well*. @@ -866,11 +857,11 @@ mybinary $(get_arguments) #### Arrays Pros -* Using Arrays allows lists of things without confusing quoting - semantics. Conversely, not using arrays leads to misguided - attempts to nest quoting inside a string. -* Arrays make it possible to safely store sequences/lists of - arbitrary strings, including strings containing whitespace. +* Using Arrays allows lists of things without confusing quoting semantics. + Conversely, not using arrays leads to misguided attempts to nest quoting + inside a string. +* Arrays make it possible to safely store sequences/lists of arbitrary + strings, including strings containing whitespace. @@ -1350,5 +1341,3 @@ no clear technical argument, nor a long-term direction. Consistency should not generally be used as a justification to do things in an old style without considering the benefits of the new style, or the tendency of the codebase to converge on newer styles over time. - -Revision 2.03