How can I avoid printing anything in Bash `printf` with an empty array?

Viewed 233

I often print out the contents of an array using a quick printf shorthand like this:

$ printf "%s\n" "${my_array[@]}"
$ printf "%s\0" "${my_array[@]}"

This works great in general:

$ my_array=(limburger stilton wensleydale)
$ printf "%s\n" "${my_array[@]}"
limburger
stilton
wensleydale
$

Works great, but when the array is empty it still outputs a single character (a newline or null byte):

$ my_array=()
$ printf "%s\n" "${my_array[@]}"

$

Of course, I can avoid that by testing first for an empty array:

$ [[ ${#my_array[@]} -gt 0 ]] && printf "%s\n" "${my_array[@]}"
$ (( ${#my_array[@]} )) && printf "%s\n" "${my_array[@]}"

But I use this idiom all the time and would prefer to keep it as short as possible. Is there a better (shorter) solution, maybe a different printf format, that won't print anything at all with an empty array?

4 Answers

Bash's parameter expansion might help:

printf "%b" "${my_array[@]/%/\\n}"

From help printf:

%b: expand backslash escape sequences in the corresponding argument

or

printf "%s" "${my_array[@]/%/$'\n'}"

For what it is worth:

(( ${#my_array[@]} )) && printf "%s\n" "${my_array[@]}"

(( ${#my_array[@]} )) is a Bash's stand-alone arithmetic expression that evaluates to true when array length is greater than 0.

Anyway, when I need to debug the content of an array. I prefer to use:

declare -p my_array

It will clearly show details that a simple printf '%s\n' cannot, like:

  • element key or index,
  • empty elements,
  • elements containing non-printable characters,
  • all of variable type or flags,
  • if array is undeclared, void declare -a my_array= or empty declare -a my_array=().

For what it's worth, a plain old for-loop works like you want. It's not shorter, but it is more obvious, so this is what I'd use for scripts instead of a shorthand.

$ my_array=(limburger stilton wensleydale)
$ for i in "${my_array[@]}"; do printf '%s\n' "$i"; done
limburger
stilton
wensleydale
$ my_array=()
$ for i in "${my_array[@]}"; do printf '%s\n' "$i"; done
$ 

There's no better solution than to test if the array is not empty.

Related