From 04a69e207927c06cb953be4d8acdcdbb229c3234 Mon Sep 17 00:00:00 2001 From: Egor Tensin Date: Tue, 5 Apr 2022 11:19:22 +0200 Subject: notes/bash: redesign --- _notes/bash.md | 120 +++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 83 insertions(+), 37 deletions(-) diff --git a/_notes/bash.md b/_notes/bash.md index 89d98fd..dfc7f57 100644 --- a/_notes/bash.md +++ b/_notes/bash.md @@ -1,69 +1,96 @@ --- title: Bash subtitle: best practices +layout: plain --- -(Associative) arrays --------------------- + +Arrays +------ ### Declaration -`"${#xs[@]}"` doesn't work with `nounset` if `xs` wasn't defined, i.e. was -declared with either of +
+
+ +```bash +local -a xs=() +declare -a xs=() +local -A xs=() +declare -A xs=() + +# Works with nounset: +echo "${#xs[@]}" +``` + +
+
```bash local -a xs declare -a xs local -A xs declare -A xs -``` - -Therefore, if you want to extract the length of an array, append `=()` to the -statements above. -```bash -local -a xs=() -declare -a xs=() +# Doesn't work with nounset: +echo "${#xs[@]}" ``` -And now `"${#xs[@]}"` works with `nounset`. -It doesn't affect expansion (see below) though. +
+
### Expansion -#### Do +
+
```bash func ${arr[@]+"${arr[@]}"} ``` -#### Don't +
+
```bash -func "${arr[@]}" # Doesn't work with `nounset`. -func "${arr[@]+"${arr[@]}"}" # Doesn't work properly with `declare -a arr=('')`. +# Doesn't work with nounset: +func "${arr[@]}" +# Doesn't work properly with `declare -a arr=('')`: +func "${arr[@]+"${arr[@]}"}" ``` +
+
+ ### `unset` -#### Do +
+
```bash unset -v 'arr[x]' unset -v 'arr[$i]' ``` -#### Don't +
+
```bash -unset -v arr[x] # May break due to globbing. -unset -v arr[$i] # The same as above + a possible problem with quotation. -unset -v 'arr["x"]' # Doesn't work for some reason. -unset -v 'arr["]"]' # The same as above; just highlighting the problem with funny characters in array indices. -unset -v 'arr["$i"]' # Also rejected. - -# An insightful discussion on the topic: https://lists.gnu.org/archive/html/help-bash/2016-09/msg00020.html. +# 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 ``` +
+
+ `errexit` --------- @@ -72,10 +99,12 @@ useful behaviour. ### Command substitution -#### Do +
+
```bash -shopt -s inherit_errexit # Without this, bar will be executed w/ errexit disabled! +# Without this, bar will be executed w/ errexit disabled! +shopt -s inherit_errexit bar() { false @@ -86,7 +115,8 @@ bar_output="$( bar )" foo "$bar_output" ``` -#### Don't +
+
```bash bar() { @@ -94,13 +124,18 @@ bar() { echo 'should never see this' >&2 } -foo "$( bar )" # Even with errexit, foo will still get executed. - # More than that, the script will print 'should never see this'! +# Even with errexit, foo will still get executed. +# More than that, the script will print 'should never see this'! +foo "$( bar )" ``` +
+
+ ### Process substitution -#### Do +
+
```bash shopt -s lastpipe @@ -110,7 +145,8 @@ command | while IFS= read -r line; do done ``` -#### Don't +
+
```bash # Without lastpipe, you cannot pipe into read: @@ -136,9 +172,13 @@ while IFS= read -r line; do done <<< "$output" ``` +
+
+ ### Functions -#### Do +
+
```bash foo() { @@ -150,13 +190,19 @@ foo echo ok ``` -#### Don't +
+
```bash +# foo will still print 'should never see this'. if foo; then - echo ok # foo will still print 'should never see this'. + echo ok fi -foo && echo ok # Same here. +# Same below. +foo && echo ok foo || echo ok ``` + +
+
-- cgit v1.2.3