/contrib/famzah

Enthusiasm never stops

Bash: Process null-terminated results piped from external commands

2 Comments

Usually when working with filenames we need to terminate each result record uniquely using the special null-character. That’s because filenames may contain special symbols, including white-space and even the newline character “\n”.

There is already a great answer how to do this in the StackOverflow topic “Capturing output of find . -print0 into a bash array”. The proposed solution doesn’t invoke any sub-shells, which is great, and also explains all caveats in detail. In order to become really universal, this solution must not rely on the static file-descriptor “3”. Another great answer at SO gives an example on how to dynamically use the next available file-descriptor.

Here is the solution which works without using sub-shells and without depending on a static FD:

a=()
while IFS='' read -r -u"$FD" -d $'\0' file; do
  # note that $IFS is having the default value here
  a+=("$file") # or however you want to process each file
done {FD}< <(find /tmp -type f -print0)
exec {FD}<&- # close the file descriptor

# the result is available outside the loop, too
echo "${a[0]}" # 1st file
echo "${a[1]}" # 2nd file

Terminal icon created by Julian Turner

Author: Ivan Zahariev

An experienced Linux & IT enthusiast, Engineer by heart, Systems architect & developer.

2 thoughts on “Bash: Process null-terminated results piped from external commands

  1. This is very clever; I had no idea bash could do this. Thank you for sharing it!

    After reading the REDIRECTION section of the bash man page, I think this example could be slightly improved by freeing up the file descriptor with something like`exec {FD}>&-` after the loop is finished.

  2. Nice catch, C! 🙂 A file descriptor is leaked, indeed. I’ve updated the example.

Leave a comment