blob: 367ee0371dc271f084b833e87106bc288a46f5ca (
plain) (
tree)
|
|
---
title: Bash
subtitle: best practices
layout: plain
links:
- {rel: stylesheet, href: 'assets/css/bash.css'}
features:
- title: Arrays
topics:
- title: Declaration
do:
- |
local -a xs=()
declare -a xs=()
local -A xs=()
declare -A xs=()
# Works with nounset:
echo "${#xs[@]}"
dont:
- |
local -a xs
declare -a xs
local -A xs
declare -A xs
# Doesn't work with nounset:
echo "${#xs[@]}"
- title: Expansion
do:
- |
func ${arr[@]+"${arr[@]}"}
dont:
- |
# Doesn't work with nounset:
func "${arr[@]}"
# Doesn't work properly with `declare -a arr=('')`:
func "${arr[@]+"${arr[@]}"}"
- title: unset
do:
- |
unset -v 'arr[x]'
unset -v 'arr[$i]'
dont:
- |
# May break due to globbing:
unset -v arr[x]
# In addition, possible quoting problem:
unset -v arr[$i]
# Doesn't work for some reason:
unset -v 'arr["x"]'
unset -v 'arr["]"]'
# Also rejected:
unset -v 'arr["$i"]'
# An insightful discussion on the topic:
# https://lists.gnu.org/archive/html/help-bash/2016-09/msg00020.html
- title: errexit
topics:
- title: Command substitution
do:
- |
# Without this, bar will be executed w/ errexit disabled!
shopt -s inherit_errexit
bar() {
false
echo 'should never see this' >&2
}
bar_output="$( bar )"
foo "$bar_output"
dont:
- |
bar() {
false
echo 'should never see this' >&2
}
# Even with errexit, foo will still get executed.
# More than that, the script will print 'should never see this'!
foo "$( bar )"
- title: Process substitution
do:
- |
shopt -s lastpipe
command | while IFS= read -r line; do
process_line "$line"
done
dont:
- |
# Without lastpipe, you cannot pipe into read:
command | while IFS= read -r line; do
process_line "$line"
done
- |
# errexit doesn't work here no matter what:
while IFS= read -r line; do
process_line "$line"
done < <( command )
echo 'should never see this'
- |
# This would break if $output contains the \0 byte:
output="$( command )"
while IFS= read -r line; do
process_line "$line"
done <<< "$output"
- title: Functions
do:
- |
foo() {
false
echo 'should never see this' >&2
}
foo
echo ok
dont:
- |
# foo will still print 'should never see this'.
if foo; then
echo ok
fi
# Same below.
foo && echo ok
foo || echo ok
---
{% for feature in page.features %}
<h2>{{ feature.title }}</h2>
{% for topic in feature.topics %}
<h3>{{ topic.title }}</h3>
<div class="row">
<div class="col-md-6">
{% for guide in topic.do %}
<div class="pre_container pre_do">
{% highlight bash %}{{ guide }}{% endhighlight %}
<div class="pre_mark"><span class="glyphicon glyphicon-ok"></span></div>
</div>
{% endfor %}
</div>
<div class="col-md-6">
{% for guide in topic.dont %}
<div class="pre_container pre_dont">
{% highlight bash %}{{ guide }}{% endhighlight %}
<div class="pre_mark"><span class="glyphicon glyphicon-remove"></span></div>
</div>
{% endfor %}
</div>
</div>
{% endfor %}
{% endfor %}
|