mirror of
https://github.com/google/styleguide.git
synced 2024-03-22 13:11:43 +08:00
Merge pull request #513 from google/change_HEAD
Update the TOC. Imported by Copybara.
This commit is contained in:
commit
f13659ba4f
145
shellguide.md
145
shellguide.md
|
@ -15,11 +15,68 @@ Revision 2.00
|
||||||
|
|
||||||
Authored, revised and maintained by many Googlers.
|
Authored, revised and maintained by many Googlers.
|
||||||
|
|
||||||
[TOC]
|
<details>
|
||||||
|
<summary>Table of Contents</summary>
|
||||||
|
|
||||||
|
- [1 Background](#s1-background)
|
||||||
|
* [1.1 Which Shell to Use](#s1.1-which-shell-to-use)
|
||||||
|
- [2 Shell Files and Interpreter Invocation](#s2-shell-files-and-interpreter-invocation)
|
||||||
|
* [2.1 File Extensions](#s2.1-file-extensions)
|
||||||
|
* [2.2 SUID/SGID](#s2.2-suid-sgid)
|
||||||
|
- [3 Environment](#s3-environment)
|
||||||
|
* [3.1 STDOUT vs STDERR](#s3.1-stdout-vs-stderr)
|
||||||
|
- [4 Comments](#s4-comments)
|
||||||
|
* [4.1 File Header](#s4.1-file-header)
|
||||||
|
+ [4.1.1 $Id$](#s4.1.1-id)
|
||||||
|
+ [4.1.2 $Id$ Pros](#s4.1.2-id-pros)
|
||||||
|
+ [4.1.3 $Id$ Cons](#s4.1.3-id-cons)
|
||||||
|
+ [4.1.4 $Id$ Decision](#s4.1.4-id-decision)
|
||||||
|
* [4.2 Function Comments](#s4.2-function-comments)
|
||||||
|
* [4.3 Implementation Comments](#s4.3-implementation-comments)
|
||||||
|
* [4.4 TODO Comments](#s4.4-todo-comments)
|
||||||
|
- [5 Formatting](#s5-formatting)
|
||||||
|
* [5.1 Indentation](#s5.1-indentation)
|
||||||
|
* [5.2 Line Length and Long Strings](#s5.2-line-length-and-long-strings)
|
||||||
|
* [5.3 Pipelines](#s5.3-pipelines)
|
||||||
|
* [5.4 Loops](#s5.4-loops)
|
||||||
|
* [5.5 Case statement](#s5.5-case-statement)
|
||||||
|
* [5.6 Variable expansion](#s5.6-variable-expansion)
|
||||||
|
* [5.7 Quoting](#s5.7-quoting)
|
||||||
|
- [6 Features and Bugs](#s6-features-and-bugs)
|
||||||
|
* [6.1 ShellCheck](#s6.1-shellcheck)
|
||||||
|
* [6.2 Command Substitution](#s6.2-command-substitution)
|
||||||
|
* [6.3 Test, `[ … ]`, and `[[ … ]]`](#s6.3-tests)
|
||||||
|
* [6.4 Testing Strings](#s6.4-testing-strings)
|
||||||
|
* [6.5 Wildcard Expansion of Filenames](#s6.5-wildcard-expansion-of-filenames)
|
||||||
|
* [6.6 Eval](#s6.6-eval)
|
||||||
|
* [6.7 Arrays](#s6.7-arrays)
|
||||||
|
+ [6.7.1 Arrays Pros](#s6.7.1-arrays-pros)
|
||||||
|
+ [6.7.2 Arrays Cons](#s6.7.2-arrays-cons)
|
||||||
|
+ [6.7.3 Arrays Decision](#s6.7.3-arrays-decision)
|
||||||
|
* [6.8 Pipes to While](#s6.8-pipes-to-while)
|
||||||
|
* [6.9 Arithmetic](#s6.9-arithmetic)
|
||||||
|
- [7 Naming Conventions](#s7-naming-conventions)
|
||||||
|
* [7.1 Function Names](#s7.1-function-names)
|
||||||
|
* [7.2 Variable Names](#s7.2-variable-names)
|
||||||
|
* [7.3 Constants and Environment Variable Names](#s7.3-constants-and-environment-variable-names)
|
||||||
|
* [7.4 Source Filenames](#s7.4-source-filenames)
|
||||||
|
* [7.5 Read-only Variables](#s7.5-read-only-variables)
|
||||||
|
* [7.6 Use Local Variables](#s7.6-use-local-variables)
|
||||||
|
* [7.7 Function Location](#s7.7-function-location)
|
||||||
|
* [7.8 main](#s7.8-main)
|
||||||
|
- [8 Calling Commands](#s8-calling-commands)
|
||||||
|
* [8.1 Checking Return Values](#s8.1-checking-return-values)
|
||||||
|
* [8.2 Builtin Commands vs. External Commands](#s8.2-builtin-commands-vs-external-commands)
|
||||||
|
- [9 Conclusion](#s9-conclusion)
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<a id="s1-background"></a>
|
||||||
|
|
||||||
## Background
|
## Background
|
||||||
|
|
||||||
|
|
||||||
|
<a id="s1.1-which-shell-to-use"></a>
|
||||||
|
|
||||||
### Which Shell to Use
|
### Which Shell to Use
|
||||||
|
|
||||||
|
@ -38,6 +95,8 @@ The only exception to this is where you're forced to by whatever
|
||||||
you're coding for. One example of this is Solaris SVR4 packages
|
you're coding for. One example of this is Solaris SVR4 packages
|
||||||
which require plain Bourne shell for any scripts.
|
which require plain Bourne shell for any scripts.
|
||||||
|
|
||||||
|
<a id="s1.1-which-shell-to-use"></a>
|
||||||
|
|
||||||
### When to use Shell
|
### When to use Shell
|
||||||
|
|
||||||
Shell should only be used for small utilities or simple wrapper
|
Shell should only be used for small utilities or simple wrapper
|
||||||
|
@ -62,8 +121,12 @@ Some guidelines:
|
||||||
to switch languages) consider whether the code is easily
|
to switch languages) consider whether the code is easily
|
||||||
maintainable by people other than its author.
|
maintainable by people other than its author.
|
||||||
|
|
||||||
|
<a id="s2-shell-files-and-interpreter-invocation"></a>
|
||||||
|
|
||||||
## Shell Files and Interpreter Invocation
|
## Shell Files and Interpreter Invocation
|
||||||
|
|
||||||
|
<a id="s2.1-file-extensions"></a>
|
||||||
|
|
||||||
### File Extensions
|
### File Extensions
|
||||||
|
|
||||||
Executables should have no extension (strongly preferred) or a
|
Executables should have no extension (strongly preferred) or a
|
||||||
|
@ -80,6 +143,8 @@ languages. This allows library files with identical purposes but
|
||||||
different languages to be identically named except for the
|
different languages to be identically named except for the
|
||||||
language-specific suffix.
|
language-specific suffix.
|
||||||
|
|
||||||
|
<a id="s2.2-suid-sgid"></a>
|
||||||
|
|
||||||
### SUID/SGID
|
### SUID/SGID
|
||||||
|
|
||||||
SUID and SGID are *forbidden* on shell scripts.
|
SUID and SGID are *forbidden* on shell scripts.
|
||||||
|
@ -91,9 +156,12 @@ which is why we're being explicit about banning it.
|
||||||
|
|
||||||
Use `sudo` to provide elevated access if you need it.
|
Use `sudo` to provide elevated access if you need it.
|
||||||
|
|
||||||
|
<a id="s3-environment"></a>
|
||||||
|
|
||||||
## Environment
|
## Environment
|
||||||
|
|
||||||
|
<a id="s3.1-stdout-vs-stderr"></a>
|
||||||
|
|
||||||
### STDOUT vs STDERR
|
### STDOUT vs STDERR
|
||||||
|
|
||||||
All error messages should go to `STDERR`.
|
All error messages should go to `STDERR`.
|
||||||
|
@ -114,9 +182,12 @@ if ! do_something; then
|
||||||
fi
|
fi
|
||||||
```
|
```
|
||||||
|
|
||||||
|
<a id="s4-comments"></a>
|
||||||
|
|
||||||
## Comments
|
## Comments
|
||||||
|
|
||||||
|
<a id="s4.1-file-header"></a>
|
||||||
|
|
||||||
### File Header
|
### File Header
|
||||||
|
|
||||||
Start each file with a description of its contents.
|
Start each file with a description of its contents.
|
||||||
|
@ -135,6 +206,8 @@ Example:
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
<a id="s4.2-function-comments"></a>
|
||||||
|
|
||||||
### Function Comments
|
### Function Comments
|
||||||
|
|
||||||
Any function that is not both obvious and short must be commented. Any
|
Any function that is not both obvious and short must be commented. Any
|
||||||
|
@ -194,6 +267,8 @@ function del_thing(arg) {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
<a id="s4.3-implementation-comments"></a>
|
||||||
|
|
||||||
### Implementation Comments
|
### Implementation Comments
|
||||||
|
|
||||||
Comment tricky, non-obvious, interesting or important parts of your
|
Comment tricky, non-obvious, interesting or important parts of your
|
||||||
|
@ -203,6 +278,8 @@ This follows general Google coding comment practice. Don't comment
|
||||||
everything. If there's a complex algorithm or you're doing something
|
everything. If there's a complex algorithm or you're doing something
|
||||||
out of the ordinary, put a short comment in.
|
out of the ordinary, put a short comment in.
|
||||||
|
|
||||||
|
<a id="s4.4-todo-comments"></a>
|
||||||
|
|
||||||
### TODO Comments
|
### TODO Comments
|
||||||
|
|
||||||
Use TODO comments for code that is temporary, a short-term solution, or
|
Use TODO comments for code that is temporary, a short-term solution, or
|
||||||
|
@ -227,12 +304,15 @@ Examples:
|
||||||
# TODO(mrmonkey): Handle the unlikely edge cases (bug ####)
|
# TODO(mrmonkey): Handle the unlikely edge cases (bug ####)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
<a id="s5-formatting"></a>
|
||||||
|
|
||||||
## Formatting
|
## Formatting
|
||||||
|
|
||||||
While you should follow the style that's already there for files that
|
While you should follow the style that's already there for files that
|
||||||
you're modifying, the following are required for any new code.
|
you're modifying, the following are required for any new code.
|
||||||
|
|
||||||
|
<a id="s5.1-indentation"></a>
|
||||||
|
|
||||||
### Indentation
|
### Indentation
|
||||||
|
|
||||||
Indent 2 spaces. No tabs.
|
Indent 2 spaces. No tabs.
|
||||||
|
@ -241,6 +321,8 @@ Use blank lines between blocks to improve readability. Indentation is
|
||||||
two spaces. Whatever you do, don't use tabs. For existing files, stay
|
two spaces. Whatever you do, don't use tabs. For existing files, stay
|
||||||
faithful to the existing indentation.
|
faithful to the existing indentation.
|
||||||
|
|
||||||
|
<a id="s5.2-line-length-and-long-strings"></a>
|
||||||
|
|
||||||
### Line Length and Long Strings
|
### Line Length and Long Strings
|
||||||
|
|
||||||
Maximum line length is 80 characters.
|
Maximum line length is 80 characters.
|
||||||
|
@ -263,6 +345,8 @@ long_string="I am an exceptionally
|
||||||
long string."
|
long string."
|
||||||
```
|
```
|
||||||
|
|
||||||
|
<a id="s5.3-pipelines"></a>
|
||||||
|
|
||||||
### Pipelines
|
### Pipelines
|
||||||
|
|
||||||
Pipelines should be split one per line if they don't all fit on one
|
Pipelines should be split one per line if they don't all fit on one
|
||||||
|
@ -286,6 +370,8 @@ command1 \
|
||||||
| command4
|
| command4
|
||||||
```
|
```
|
||||||
|
|
||||||
|
<a id="s5.4-loops"></a>
|
||||||
|
|
||||||
### Loops
|
### Loops
|
||||||
|
|
||||||
Put `; do` and `; then` on the same line as the
|
Put `; do` and `; then` on the same line as the
|
||||||
|
@ -320,6 +406,8 @@ for dir in "${dirs_to_cleanup[@]}"; do
|
||||||
done
|
done
|
||||||
```
|
```
|
||||||
|
|
||||||
|
<a id="s5.5-case-statement"></a>
|
||||||
|
|
||||||
### Case statement
|
### Case statement
|
||||||
|
|
||||||
* Indent alternatives by 2 spaces.
|
* Indent alternatives by 2 spaces.
|
||||||
|
@ -374,6 +462,8 @@ while getopts 'abf:v' flag; do
|
||||||
done
|
done
|
||||||
```
|
```
|
||||||
|
|
||||||
|
<a id="s5.6-variable-expansion"></a>
|
||||||
|
|
||||||
### Variable expansion
|
### Variable expansion
|
||||||
|
|
||||||
In order of precedence: Stay consistent with what you find; quote your
|
In order of precedence: Stay consistent with what you find; quote your
|
||||||
|
@ -430,6 +520,8 @@ They are listed in order of precedence.
|
||||||
NOTE: Using braces in `${var}` is *not* a form of quoting. "Double quotes" must
|
NOTE: Using braces in `${var}` is *not* a form of quoting. "Double quotes" must
|
||||||
be used *as well*.
|
be used *as well*.
|
||||||
|
|
||||||
|
<a id="s5.7-quoting"></a>
|
||||||
|
|
||||||
### Quoting
|
### Quoting
|
||||||
|
|
||||||
* Always quote strings containing variables, command substitutions, spaces or
|
* Always quote strings containing variables, command substitutions, spaces or
|
||||||
|
@ -516,14 +608,22 @@ grep -cP '([Ss]pecial|\|?characters*)$' ${1:+"$1"}
|
||||||
(set -- 1 "2 two" "3 three tres"; echo $#; set -- "$@"; echo "$#, $@")
|
(set -- 1 "2 two" "3 three tres"; echo $#; set -- "$@"; echo "$#, $@")
|
||||||
```
|
```
|
||||||
|
|
||||||
|
<a id="s6-features-and-bugs"></a>
|
||||||
|
|
||||||
## Features and Bugs
|
## Features and Bugs
|
||||||
|
|
||||||
|
<a id="s6.1-shelllint"></a>
|
||||||
|
|
||||||
|
<a id="s6.1-shellcheck"></a>
|
||||||
|
|
||||||
### ShellCheck
|
### ShellCheck
|
||||||
|
|
||||||
The [ShellCheck project](https://www.shellcheck.net/) identifies common bugs and
|
The [ShellCheck project](https://www.shellcheck.net/) identifies common bugs and
|
||||||
warnings for your shell scripts. It is recommended for all scripts, large or
|
warnings for your shell scripts. It is recommended for all scripts, large or
|
||||||
small.
|
small.
|
||||||
|
|
||||||
|
<a id="s6.2-command-substitution"></a>
|
||||||
|
|
||||||
### Command Substitution
|
### Command Substitution
|
||||||
|
|
||||||
Use `$(command)` instead of backticks.
|
Use `$(command)` instead of backticks.
|
||||||
|
@ -544,6 +644,8 @@ var="$(command "$(command1)")"
|
||||||
var="`command \`command1\``"
|
var="`command \`command1\``"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
<a id="s6.3-tests"></a>
|
||||||
|
|
||||||
<a id="tests"></a>
|
<a id="tests"></a>
|
||||||
### Test, `[ … ]`, and `[[ … ]]`
|
### Test, `[ … ]`, and `[[ … ]]`
|
||||||
|
|
||||||
|
@ -578,6 +680,8 @@ fi
|
||||||
|
|
||||||
For the gory details, see E14 at http://tiswww.case.edu/php/chet/bash/FAQ
|
For the gory details, see E14 at http://tiswww.case.edu/php/chet/bash/FAQ
|
||||||
|
|
||||||
|
<a id="s6.4-testing-strings"></a>
|
||||||
|
|
||||||
### Testing Strings
|
### Testing Strings
|
||||||
|
|
||||||
Use quotes rather than filler characters where possible.
|
Use quotes rather than filler characters where possible.
|
||||||
|
@ -664,6 +768,8 @@ if [[ "${my_var}" > 3 ]]; then
|
||||||
fi
|
fi
|
||||||
```
|
```
|
||||||
|
|
||||||
|
<a id="s6.5-wildcard-expansion-of-filenames"></a>
|
||||||
|
|
||||||
### Wildcard Expansion of Filenames
|
### Wildcard Expansion of Filenames
|
||||||
|
|
||||||
Use an explicit path when doing wildcard expansion of filenames.
|
Use an explicit path when doing wildcard expansion of filenames.
|
||||||
|
@ -690,6 +796,8 @@ rm: cannot remove `./somedir': Is a directory
|
||||||
removed `./somefile'
|
removed `./somefile'
|
||||||
```
|
```
|
||||||
|
|
||||||
|
<a id="s6.6-eval"></a>
|
||||||
|
|
||||||
### Eval
|
### Eval
|
||||||
|
|
||||||
`eval` should be avoided.
|
`eval` should be avoided.
|
||||||
|
@ -707,6 +815,8 @@ eval $(set_my_variables)
|
||||||
variable="$(eval some_function)"
|
variable="$(eval some_function)"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
<a id="s6.7-arrays"></a>
|
||||||
|
|
||||||
### Arrays
|
### Arrays
|
||||||
|
|
||||||
Bash arrays should be used to store lists of elements, to avoid quoting
|
Bash arrays should be used to store lists of elements, to avoid quoting
|
||||||
|
@ -747,6 +857,8 @@ declare -a files=($(ls /directory))
|
||||||
mybinary $(get_arguments)
|
mybinary $(get_arguments)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
<a id="s6.7.1-arrays-pros"></a>
|
||||||
|
|
||||||
#### Arrays Pros
|
#### Arrays Pros
|
||||||
|
|
||||||
* Using Arrays allows lists of things without confusing quoting
|
* Using Arrays allows lists of things without confusing quoting
|
||||||
|
@ -755,10 +867,14 @@ mybinary $(get_arguments)
|
||||||
* Arrays make it possible to safely store sequences/lists of
|
* Arrays make it possible to safely store sequences/lists of
|
||||||
arbitrary strings, including strings containing whitespace.
|
arbitrary strings, including strings containing whitespace.
|
||||||
|
|
||||||
|
<a id="s6.7.2-arrays-cons"></a>
|
||||||
|
|
||||||
#### Arrays Cons
|
#### Arrays Cons
|
||||||
|
|
||||||
Using arrays can risk a script’s complexity growing.
|
Using arrays can risk a script’s complexity growing.
|
||||||
|
|
||||||
|
<a id="s6.7.3-arrays-decision"></a>
|
||||||
|
|
||||||
#### Arrays Decision
|
#### Arrays Decision
|
||||||
|
|
||||||
Arrays should be used to safely create and pass around lists. In
|
Arrays should be used to safely create and pass around lists. In
|
||||||
|
@ -768,6 +884,8 @@ avoid confusing quoting issues. Use quoted expansion –
|
||||||
advanced data manipulation is required, shell scripting should be
|
advanced data manipulation is required, shell scripting should be
|
||||||
avoided altogether; see [above](#when-to-use-shell).
|
avoided altogether; see [above](#when-to-use-shell).
|
||||||
|
|
||||||
|
<a id="s6.8-pipes-to-while"></a>
|
||||||
|
|
||||||
### Pipes to While
|
### Pipes to While
|
||||||
|
|
||||||
Use process substitution or for loops in preference to piping to while.
|
Use process substitution or for loops in preference to piping to while.
|
||||||
|
@ -833,6 +951,8 @@ while read src dest type opts rest; do
|
||||||
done < /proc/mounts
|
done < /proc/mounts
|
||||||
```
|
```
|
||||||
|
|
||||||
|
<a id="s6.9-arithmetic"></a>
|
||||||
|
|
||||||
### Arithmetic
|
### Arithmetic
|
||||||
|
|
||||||
Always use `(( … ))` or `$(( … ))` rather than
|
Always use `(( … ))` or `$(( … ))` rather than
|
||||||
|
@ -915,9 +1035,12 @@ sec=30
|
||||||
echo $(( hr * 3600 + min * 60 + sec )) # prints 7530 as expected
|
echo $(( hr * 3600 + min * 60 + sec )) # prints 7530 as expected
|
||||||
```
|
```
|
||||||
|
|
||||||
|
<a id="s7-naming-conventions"></a>
|
||||||
|
|
||||||
## Naming Conventions
|
## Naming Conventions
|
||||||
|
|
||||||
|
<a id="s7.1-function-names"></a>
|
||||||
|
|
||||||
### Function Names
|
### Function Names
|
||||||
|
|
||||||
Lower-case, with underscores to separate words. Separate libraries with
|
Lower-case, with underscores to separate words. Separate libraries with
|
||||||
|
@ -947,6 +1070,8 @@ The `function` keyword is extraneous when "()" is present
|
||||||
after the function name, but enhances quick identification of
|
after the function name, but enhances quick identification of
|
||||||
functions.
|
functions.
|
||||||
|
|
||||||
|
<a id="s7.2-variable-names"></a>
|
||||||
|
|
||||||
### Variable Names
|
### Variable Names
|
||||||
|
|
||||||
As for function names.
|
As for function names.
|
||||||
|
@ -960,6 +1085,8 @@ for zone in "${zones[@]}"; do
|
||||||
done
|
done
|
||||||
```
|
```
|
||||||
|
|
||||||
|
<a id="s7.3-constants-and-environment-variable-names"></a>
|
||||||
|
|
||||||
### Constants and Environment Variable Names
|
### Constants and Environment Variable Names
|
||||||
|
|
||||||
All caps, separated with underscores, declared at the top of the file.
|
All caps, separated with underscores, declared at the top of the file.
|
||||||
|
@ -991,6 +1118,8 @@ done
|
||||||
readonly VERBOSE
|
readonly VERBOSE
|
||||||
```
|
```
|
||||||
|
|
||||||
|
<a id="s7.4-source-filenames"></a>
|
||||||
|
|
||||||
### Source Filenames
|
### Source Filenames
|
||||||
|
|
||||||
Lowercase, with underscores to separate words if desired.
|
Lowercase, with underscores to separate words if desired.
|
||||||
|
@ -999,6 +1128,8 @@ This is for consistency with other code styles in Google:
|
||||||
`maketemplate` or `make_template` but not
|
`maketemplate` or `make_template` but not
|
||||||
`make-template`.
|
`make-template`.
|
||||||
|
|
||||||
|
<a id="s7.5-read-only-variables"></a>
|
||||||
|
|
||||||
### Read-only Variables
|
### Read-only Variables
|
||||||
|
|
||||||
Use `readonly` or `declare -r` to ensure they're
|
Use `readonly` or `declare -r` to ensure they're
|
||||||
|
@ -1017,6 +1148,8 @@ else
|
||||||
fi
|
fi
|
||||||
```
|
```
|
||||||
|
|
||||||
|
<a id="s7.6-use-local-variables"></a>
|
||||||
|
|
||||||
### Use Local Variables
|
### Use Local Variables
|
||||||
|
|
||||||
Declare function-specific variables with `local`. Declaration
|
Declare function-specific variables with `local`. Declaration
|
||||||
|
@ -1056,6 +1189,8 @@ my_func2() {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
<a id="s7.7-function-location"></a>
|
||||||
|
|
||||||
### Function Location
|
### Function Location
|
||||||
|
|
||||||
Put all functions together in the file just below constants. Don't hide
|
Put all functions together in the file just below constants. Don't hide
|
||||||
|
@ -1068,6 +1203,8 @@ may be done before declaring functions.
|
||||||
Don't hide executable code between functions. Doing so makes the code
|
Don't hide executable code between functions. Doing so makes the code
|
||||||
difficult to follow and results in nasty surprises when debugging.
|
difficult to follow and results in nasty surprises when debugging.
|
||||||
|
|
||||||
|
<a id="s7.8-main"></a>
|
||||||
|
|
||||||
### main
|
### main
|
||||||
|
|
||||||
A function called `main` is required for scripts long enough
|
A function called `main` is required for scripts long enough
|
||||||
|
@ -1087,9 +1224,12 @@ main "$@"
|
||||||
Obviously, for short scripts where it's just a linear flow,
|
Obviously, for short scripts where it's just a linear flow,
|
||||||
`main` is overkill and so is not required.
|
`main` is overkill and so is not required.
|
||||||
|
|
||||||
|
<a id="s8-calling-commands"></a>
|
||||||
|
|
||||||
## Calling Commands
|
## Calling Commands
|
||||||
|
|
||||||
|
<a id="s8.1-checking-return-values"></a>
|
||||||
|
|
||||||
### Checking Return Values
|
### Checking Return Values
|
||||||
|
|
||||||
Always check return values and give informative return values.
|
Always check return values and give informative return values.
|
||||||
|
@ -1143,6 +1283,8 @@ if (( return_codes[1] != 0 )); then
|
||||||
fi
|
fi
|
||||||
```
|
```
|
||||||
|
|
||||||
|
<a id="s8.2-builtin-commands-vs-external-commands"></a>
|
||||||
|
|
||||||
### Builtin Commands vs. External Commands
|
### Builtin Commands vs. External Commands
|
||||||
|
|
||||||
Given the choice between invoking a shell builtin and invoking a
|
Given the choice between invoking a shell builtin and invoking a
|
||||||
|
@ -1166,6 +1308,7 @@ addition="$(expr ${X} + ${Y})"
|
||||||
substitution="$(echo "${string}" | sed -e 's/^foo/bar/')"
|
substitution="$(echo "${string}" | sed -e 's/^foo/bar/')"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
<a id="s9-conclusion"></a>
|
||||||
|
|
||||||
## Conclusion
|
## Conclusion
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user