[bash] the <<<$DATA issue
am 11.01.2008 18:06:28 von guisep4
When I need to modify vars inside while loop, I try to use <<<$DATA
instead of
follows.
Generally, the following two forms are expected to be equivalent,
no ?:
1) while read x; do ... ; done
2) DATA="`cat
Except for the case when file is empty. Then 2nd form does not work
right for me:
a)
while read x; do echo "<>"; done
# correct: does not print anything
b)
DATA="`cat >" ; done
<<<"$DATA"
# wrong: prints <<>> once
Why second form enters the loop once in (b) ? Is it a bash bug ?
Thanks
G.G.
Re: [bash] the <<<$DATA issue
am 11.01.2008 20:17:04 von Stephane CHAZELAS
On Fri, 11 Jan 2008 09:06:28 -0800 (PST), guisep4@gmail.com wrote:
> When I need to modify vars inside while loop, I try to use <<<$DATA
> instead of
> follows.
>
> Generally, the following two forms are expected to be equivalent,
> no ?:
>
> 1) while read x; do ... ; done
> 2) DATA="`cat
>
> Except for the case when file is empty. Then 2nd form does not work
> right for me:
> a)
> while read x; do echo "<>"; done
> # correct: does not print anything
> b)
> DATA="`cat >" ; done
> <<<"$DATA"
> # wrong: prints <<>> once
>
> Why second form enters the loop once in (b) ? Is it a bash bug ?
[...]
because otherwise
read foo <<< bar
wouldn't put anything into $foo.
The cmd <<< xxx syntax (that comes from the "rc" shell, through
zsh), stores "xxx" followed by a NL character into a temporary
file and opens that file for reading as the standard input of
cmd.
$ od -c <<< ''
0000000 \n
0000001
The thing is that for non-empty files,
foo=`cat < file`
removes the trailing NLs (yes all of them, however strange and
inapropriate that may seem), and <<< restores one.
For an empty file, there's no NL that `...` may remove and <<<
adds one nonetheless.
You could do instead:
data=`cat < "$file"; echo .`; data=${data%.}
# that stores the content of the file exactly as long as it
# doesn't contain NUL bytes (except for zsh that supports NUL
# bytes.
and then:
printf %s "$data" | {
while IFS= read -r line; do
printf '<<%s>>\n' "$line";
done
if [ -n "$line" ]; then
printf 'There was something after the last NL: <<%s>>\n' "$line"
fi
}
Another illustration of why you should avoid "while read" loops.
--
Stephane
Re: [bash] the <<<$DATA issue
am 11.01.2008 20:26:32 von Stephane CHAZELAS
On 11 Jan 2008 19:17:04 GMT, Stephane Chazelas wrote:
[...]
>> 2) DATA="`cat
[...]
>> Why second form enters the loop once in (b) ? Is it a bash bug ?
> [...]
>
> because otherwise
>
> read foo <<< bar
>
> wouldn't put anything into $foo.
[...]
Well, it would put "bar" in $foo, but would return false because
it didn't manage to read a full line (that is, up to the
terminating NL).
--
Stephane