From 86bd5f8016919d971b7289811465426d28cf0a31 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Fri, 8 Jan 2021 09:27:06 +0200 Subject: Reorder sections in Bash style guide --- doc/bash-style.cli | 318 +++++++++++++++++++++++++++-------------------------- 1 file changed, 160 insertions(+), 158 deletions(-) diff --git a/doc/bash-style.cli b/doc/bash-style.cli index 17a850d..435dfe3 100644 --- a/doc/bash-style.cli +++ b/doc/bash-style.cli @@ -287,6 +287,28 @@ echo \"files: ${files[@]}\" # $1='files: one', $2='2 two', $3='three' echo \"files: ${files[*]}\" # $1='files: one 2 two three' \ + +\h1#bool|Boolean| + +For boolean values use empty for false and \c{true} for true. This way you +can have terse and natural looking conditions, for example: + +\ +first=true +while ...; do + + if [ ! \"$first\" ]; then + ... + fi + + if [ \"$first\" ]; then + first= + fi + +done +\ + + \h1#subshell|Subshell| Bush executes certain constructs in \i{subshells} and some of these constructs @@ -346,6 +368,144 @@ done \N|The \c{lastpipe} shell option is inherited by functions and subshells.| +\h1#function|Functions| + +If a function takes arguments, provide a brief usage after the function +header, for example: + +\ +function dist() # +{ + ... +} +\ + +For non-trivial/obvious functions also provide a short description of its +functionality/purpose, for example: + +\ +# Prepare a distribution of the specified packages and place it +# into the specified directory. +# +function dist() # +{ + ... +} +\ + +Inside functions use local variables, for example: + +\ +function dist() +{ + local x=\"foo\" +} +\ + +If the evaluation of the value may fail (e.g., it contains a program +substitution), then place the assignment on a separate line since \c{local} +will cause the error to be ignored. For example: + +\ +function dist() +{ + local b + b=\"$(basename \"$2\")\" +} +\ + +A function can return data in two primary ways: exit code and stdout. +Normally, exit code 0 means success and exit code 1 means failure though +additional codes can be used to distinguish between different kinds of +failures, signify special conditions, etc., see \l{#error-handing Error +Handling} for details. + +A function can also write to stdout with the result available to the caller in +the same way as from programs (command substitution, pipeline, etc). If a +function needs to return multiple values, then it can print them separated +with newlines with the caller using the \c{readarray} builtin to read them +into an indexed array, for example: + +\ +function foo () +{ + echo one + echo two + echo three +} + +foo | readarray -t r +\ + +In this case, if the function can fail, then the failure should be explicitly +checked for (either by examining \c{PIPESTATUS} or via the lack of the +result), since the error trap will not be triggered (unless the \c{pipefail} +shell option is set; see \l{#error-handing Error Handling} for details). For +example: + +\ +foo | readarray -t r + +if [ \"${PIPESTATUS[0]}\" -ne 0 ]; then + exit 1 +fi +\ + +\N|The use of the newline as a separator means that values may not contain +newlines. While \c{readarray} supports specifying a custom separator with the +\c{-d} option, including a \c{NUL} separator, this support is only available +since Bash 4.4.| + +This technique can also be extended to return an associative array by +returning the values as an indexed array and then converting them to +an associative array with \c{eval}, for example: + +\ +function foo () +{ + echo \"[a]=one\" + echo \"[b]=two\" + echo \"[c]=three\" +} + +foo | readarray -t ia + +if [ \"${PIPESTATUS[0]}\" -ne 0 ]; then + exit 1 +fi + +eval declare -A aa=(\"${ia[@]}\") +\ + +Note that if a key or a value contains whitespaces, then it must be quoted. +The recommendation is to always quote both, for example: + +\ +function foo () +{ + echo \"['a']='one ONE'\" + echo \"['b']='two'\" + echo \"['c']='three'\" +} +\ + +Or, if returning a local array: + +\ +function foo () +{ + declare -A a=([a]='one ONE' [b]=two [c]=three) + + for k in \"${!a[@]}\"; do + echo \"['$k']='${a[$k]}'\" + done +} +\ + +For more information on returning data from functions, see +\l{https://mywiki.wooledge.org/BashFAQ/084 BashFAQ#084}. + + \h1#error-handing|Error Handling| Our scripts use the error trap to automatically terminate the script in case @@ -510,162 +670,4 @@ esac \N|We use \c{readarray} instead of \c{read} since the latter fails if the left hand side of the pipeline does not produce anything.| - -\h1#bool|Boolean| - -For boolean values use empty for false and \c{true} for true. This way you -can have terse and natural looking conditions, for example: - -\ -first=true -while ...; do - - if [ ! \"$first\" ]; then - ... - fi - - if [ \"$first\" ]; then - first= - fi - -done -\ - -\h1#function|Functions| - -If a function takes arguments, provide a brief usage after the function -header, for example: - -\ -function dist() # -{ - ... -} -\ - -For non-trivial/obvious functions also provide a short description of its -functionality/purpose, for example: - -\ -# Prepare a distribution of the specified packages and place it -# into the specified directory. -# -function dist() # -{ - ... -} -\ - -Inside functions use local variables, for example: - -\ -function dist() -{ - local x=\"foo\" -} -\ - -If the evaluation of the value may fail (e.g., it contains a program -substitution), then place the assignment on a separate line since \c{local} -will cause the error to be ignored. For example: - -\ -function dist() -{ - local b - b=\"$(basename \"$2\")\" -} -\ - -A function can return data in two primary ways: exit code and stdout. -Normally, exit code 0 means success and exit code 1 means failure though -additional codes can be used to distinguish between different kinds of -failures, signify special conditions, etc., see \l{#error-handing Error -Handling} for details. - -A function can also write to stdout with the result available to the caller in -the same way as from programs (command substitution, pipeline, etc). If a -function needs to return multiple values, then it can print them separated -with newlines with the caller using the \c{readarray} builtin to read them -into an indexed array, for example: - -\ -function foo () -{ - echo one - echo two - echo three -} - -foo | readarray -t r -\ - -In this case, if the function can fail, then the failure should be explicitly -checked for (either by examining \c{PIPESTATUS} or via the lack of the -result), since the error trap will not be triggered (unless the \c{pipefail} -shell option is set; see \l{#error-handing Error Handling} for details). For -example: - -\ -foo | readarray -t r - -if [ \"${PIPESTATUS[0]}\" -ne 0 ]; then - exit 1 -fi -\ - -\N|The use of the newline as a separator means that values may not contain -newlines. While \c{readarray} supports specifying a custom separator with the -\c{-d} option, including a \c{NUL} separator, this support is only available -since Bash 4.4.| - -This technique can also be extended to return an associative array by -returning the values as an indexed array and then converting them to -an associative array with \c{eval}, for example: - -\ -function foo () -{ - echo \"[a]=one\" - echo \"[b]=two\" - echo \"[c]=three\" -} - -foo | readarray -t ia - -if [ \"${PIPESTATUS[0]}\" -ne 0 ]; then - exit 1 -fi - -eval declare -A aa=(\"${ia[@]}\") -\ - -Note that if a key or a value contains whitespaces, then it must be quoted. -The recommendation is to always quote both, for example: - -\ -function foo () -{ - echo \"['a']='one ONE'\" - echo \"['b']='two'\" - echo \"['c']='three'\" -} -\ - -Or, if returning a local array: - -\ -function foo () -{ - declare -A a=([a]='one ONE' [b]=two [c]=three) - - for k in \"${!a[@]}\"; do - echo \"['$k']='${a[$k]}'\" - done -} -\ - -For more information on returning data from functions, see -\l{https://mywiki.wooledge.org/BashFAQ/084 BashFAQ#084}. - " -- cgit v1.1