blob: ea0cb8a0c982ddfc0972e862b482ebfb6c5000e5 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
|
---
title: Bash
subtitle: best practices
layout: plain
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 %}
{% highlight bash %}{{ guide }}{% endhighlight %}
{% endfor %}
</div>
<div class="col-md-6">
{% for guide in topic.dont %}
{% highlight bash %}{{ guide }}{% endhighlight %}
{% endfor %}
</div>
</div>
{% endfor %}
{% endfor %}
|