#!/usr/bin/env bash set -o errexit -o nounset -o pipefail shopt -s inherit_errexit lastpipe
#!/bin/sh -e
local -a xs=() declare -a xs=() local -A xs=() declare -A xs=()
local -a xs declare -a xs local -A xs declare -A xs # Doesn't work with nounset: echo "${#xs[@]}"
func ${arr[@]+"${arr[@]}"}
# Doesn't work with nounset: func "${arr[@]}"
# Expands to 0 arguments instead of 1: declare -a arr=('') func "${arr[@]+"${arr[@]}"}"
unset -v 'arr[x]' unset -v 'arr[$i]'
# 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
shopt -s inherit_errexit foo() { echo foo ; } bar() { false ; echo bar >&2 ; } output="$( bar )" foo "$output" # If inherit_errexit is unavailable, you can do #output="$( set -e; bar )"
foo() { echo foo ; } bar() { false ; echo bar >&2 ; } # This will print both "foo" and "bar": foo "$( bar )" # This will also print "foo": foo "$( false )"
foo() { echo foo ; } bar() { false ; echo bar >&2 ; } # This will still print both "foo" and "bar". output="$( bar )" foo "$output" # This won't print anything. output="$( false )" foo "$output"
shopt -s lastpipe result=() cmd | while IFS= read -r line; do result+=("$( process_line "$line" )") done
# Without lastpipe, the loop is executed is a subshell, # and the array will be empty: result=() cmd | while IFS= read -r line; do result+=("$( process_line "$line" )") done
# errexit doesn't work for <( cmd ) no matter what: while IFS= read -r line; do process_line "$line" done < <( cmd ) # This will be printed even if cmd fails: echo 'should never see this'
# This breaks if $output contains the \0 byte: output="$( cmd )" while IFS= read -r line; do process_line "$line" done <<< "$output"
foo() { false ; echo foo >&2 ; } foo echo ok
foo() { false ; echo foo >&2 ; } # This will print "foo" no matter what. if foo; then echo ok fi # Same below. foo && echo ok foo || echo fail # It currently appears to be completely impossible to # execute a function inside a conditional with errexit # enabled. Therefore, you should try to avoid this # whenever possible.