-
Notifications
You must be signed in to change notification settings - Fork 382
Bash Style guide
This document is so that others can collaborate with me in my open source projects. It's primarily based on http://wiki.bash-hackers.org/scripting/style along with my own experiences over the years.
Keep in mind this is not for general shell scripting, these are rules specifically for Bash and can take advantage of assumptions around Bash as the interpreter.
- Indent code using 2 spaces.
- Always double quote variables, including subshells. No naked
$
signs- This rule gets you pretty far. Read http://mywiki.wooledge.org/Quotes for details
- Never use deprecated style. Most notably:
- Define functions as
myfunc() { ... }
, notfunction myfunc { ... }
- Always use
[[
instead of[
ortest
- Never use backticks, use
$( ... )
- See http://wiki.bash-hackers.org/scripting/obsolete for more
- Define functions as
- Use
mktemp
for temporary files, always cleanup with atrap
. - Prefer absolute paths (leverage $PWD), always qualify relative paths with
./
.
- Use Bash variable substitution if possible before awk/sed.
- Generally use double quotes unless it makes more sense to use single quotes.
- For simple conditionals, try using
&&
and||
. - Don't be afraid of
printf
, it's more powerful thanecho
. - Put
then
,do
, etc on same line, not newline. - Skip
[[ ... ]]
in your if-expression if you can test for exit code instead. - Use
.sh
or.bash
extension if file is meant to be included/sourced. Never on executable script. - Put complex one-liners of
sed
,perl
, etc in a standalone function with a descriptive name. - Design for simplicity and obvious usage.
- Avoid option flags and parsing, try optional environment variables instead.
- Use subcommands for necessary different "modes".
- Be conscious of the need for portability.
- http://wiki.bash-hackers.org/scripting/start
- http://tldp.org/LDP/abs/html/
- Tips for interactive Bash: http://samrowe.com/wordpress/advancing-in-the-bash-shell/
- For reference, Google's Bash styleguide
Indentation is nothing that technically influences a script, however with 2 spaces
- it's easy and fast to type
- it's not a hard-tab that's displayed differently in different environments
- it's wide enough to give a visual break and small enough to not waste too much space on the line
tabs should be avoided other than in here-document where it helps the indentation.
Put the introducing keyword and the initial command list or parameters on one line ("head") Indent the body statements within the command Put the closing keyword on a separated line, indented like the initial introducing keyword
examples ....
if, then
if ...; then
...
elif ...; then
...
else
...
fi
for
for f in /etc/*; do
...
done
while/until
while [[ $answer != [YyNn] ]]; do
...
done
Cryptic constructs, we all know them. If they are not 100% needed, avoid them, since nobody except you may be able to decipher them.
If you need to use a cryptic construct, include a comment that explains in detail what your "monster" does.
Ensure your code is readable - an example from http://mywiki.wooledge.org/BashGuide/Practices
This first version of code would work ....
1 x=( Marcus\ The\ Rich JJ\ The\ Short
2 Timid\ Thomas Michelangelo\ The\ Mobster)
3 for name in "${x[@]}"
4 do if [ "$name" = "$x" ]; then echo $name was my first friend.
5 elif
6 echo $name | \
7 grep -qw Short
8 then echo $name is a shorty.
9 elif [ "x${name:0:1}" = "xM" ]
10 then echo $name starts with an M; else
11 echo I kind of forgot what $name \
12 is like.; fi; done
This second version is much easier to read, and still works :) so please use something closer to this second version.
1 friends=( "Marcus The Rich" "JJ The Short" "Timid Thomas" "Michelangelo The Mobster" )
2
3 # Say something significant about my friends.
4 for name in "${friends[@]}"; do
5
6 # My first friend (in the list).
7 if [[ $name = "${friends[0]}" ]]; then
8 echo "$name was my first friend."
9
10 # My friends whose names start with M.
11 elif [[ $name = M* ]]; then
12 echo "$name starts with an M"
13
14 # My short friends.
15 elif [[ " $name " = *" Short "* ]]; then
16 echo "$name is a shorty."
17
18 # Friends I kind of didn't bother to remember.
19 else
20 echo "I kind of forgot what $name is like."
21
22 fi
23 done