Pregunta

I'm relatively new to shell scripting, but not to programming, though I'll admit to being out of the game for a while.

In trying to get the bottom of a bug in a Bash script, I've come up with three short examples of my use of process substitution and "here strings" feeding STDIN for while loops, in order to avoid subshell issues.

I'm null-separating the find output to avoid potential struggles with unusual filename characters.

This example works great, and outputs the names of all folders in root:

#!/bin/bash
while IFS= read -r -d '' y; do echo "${y}"
done < <(find / -type d -maxdepth 1 -mindepth 1 -printf "%P\0" | sort -z)

This example works great, too:

#!/bin/bash
find / -type d -maxdepth 1 -mindepth 1 -printf "%P\0" | sort -z | \
{ while IFS= read -r -d '' y; do echo "${y}"; done }

But this case, where I store the find output in string x and attempt to use it as the source of my "here string", outputs nothing:

#!/bin/bash
x=$(find / -type d -maxdepth 1 -mindepth 1 -printf "%P\0" | sort -z)
while IFS= read -r -d '' y; do echo "${y}"; done <<< "${x}"

What subtlety (or denseness on my part) am I missing here?

I'm using GNU bash 4.1.7(2)-release.

¿Fue útil?

Solución

Strings in bash are like C-strings and are null-terminated. This should explain why it doesn't work when you try to assign the output to a variable.

As an experiment, you could try

a=$'foo\0bar'
echo "$a"

Otros consejos

When you assign a string to a parameter, the end of the string is terminated by the first null character. The shell can, however, pass null-character-containing strings via standard input, which can read an arbitrary byte stream.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top