# https://vaneyckt.io/posts/safer_bash_scripts_with_set_euxo_pipefail/ set -Eeuxo pipefail Best practices from Google: # --- Process file line-by-line (don't pipe to 'while', use process substitution) last_line='NULL' while read line; do if [[ -n "${line}" ]]; then last_line="${line}" fi done < <(your_command) # This will output the last non-empty line from your_command echo "${last_line}" ## ... OR ... last_line='NULL' readarray -t lines < <(your_command) for line in "${lines[@]}"; do if [[ -n "${line}" ]]; then last_line="${line}" fi done echo "${last_line}" # This will output the last non-empty line from your_command echo "${last_line}" # --- Testing strings # Do this: if [[ "${my_var}" == "some_string" ]]; then do_something fi # -z (string length is zero) and -n (string length is not zero) are # preferred over testing for an empty string if [[ -z "${my_var}" ]]; then do_something fi # This is OK (ensure quotes on the empty side), but not preferred: if [[ "${my_var}" == "" ]]; then do_something fi # --- Arrays # An array is assigned using parentheses, and can be appended to # with +=( … ). declare -a flags flags=(--foo --bar='baz') flags+=(--greeting="Hello ${name}") mybinary "${flags[@]}" # --- Check return status if ! mv "${file_list[@]}" "${dest_dir}/"; then echo "Unable to move ${file_list[*]} to ${dest_dir}" >&2 exit 1 fi ## ... or ... mv "${file_list[@]}" "${dest_dir}/" if (( $? != 0 )); then echo "Unable to move ${file_list[*]} to ${dest_dir}" >&2 exit 1 fi