aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/_notes/bash.html
diff options
context:
space:
mode:
Diffstat (limited to '_notes/bash.html')
-rw-r--r--_notes/bash.html146
1 files changed, 146 insertions, 0 deletions
diff --git a/_notes/bash.html b/_notes/bash.html
new file mode 100644
index 0000000..ea0cb8a
--- /dev/null
+++ b/_notes/bash.html
@@ -0,0 +1,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 %}