help-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: printf '%s\n' "$@" versus <<< redirection


From: Kerin Millar
Subject: Re: printf '%s\n' "$@" versus <<< redirection
Date: Sun, 19 Feb 2023 16:07:40 +0000

On Sun, 19 Feb 2023 09:02:49 -0500
Greg Wooledge <greg@wooledge.org> wrote:

> On Sun, Feb 19, 2023 at 10:38:22AM +0000, Kerin Millar wrote:
> > $ printf 'n\n' | { IFS='\n' read -r vl; declare -p vl; }
> > declare -- vl=""
> 
> What the hell...?

I'll have a go at explaining it. Looking at 
https://pubs.opengroup.org/onlinepubs/9699919799/utilities/read.html, a 
particular behaviour is described for the case where the number of fields ends 
up being greater than the number of specified names, affecting the second, 
fourth and sixth of your test cases.

> 
> unicorn:~$ printf 'n\n' | { IFS='\n' read -r vl; declare -p vl; } 
> declare -- vl=""

There is one "n"-terminated field, matching the number of specified names. Its 
value is "", which is assigned.

> unicorn:~$ printf 'no\n' | { IFS='\n' read -r vl; declare -p vl; } 
> declare -- vl="no"

There are two fields, the first of which is terminated by "n", not matching the 
number of specified names. Their values are "" and "o", respectively. The 
assignment thus comprises "", the delimiter following that field ("n") and the 
remaining fields and their delimiters ("o" - there was no delimiter). Thus, 
"no" is assigned.

> unicorn:~$ printf 'on\n' | { IFS='\n' read -r vl; declare -p vl; } 
> declare -- vl="o"

There is one "n"-terminated field, matching the number of specified names. Its 
valid is "o", which is assigned.

> unicorn:~$ printf 'noon\n' | { IFS='\n' read -r vl; declare -p vl; } 
> declare -- vl="noon"

There are two "n"-terminated fields, not matching the number of specified 
names. Their values are "" and "oo" respectively. The assignment thus comprises 
"", the delimiter following that field ("n") and the remaining fields and their 
delimiters ("oon"). Thus, "noon" is assigned.

> 
> What is it doing there?  And why?
> 
> Also:
> 
> unicorn:~$ bash-2.05b
> unicorn:~$ printf 'n\n' | { IFS='\n' read -r vl; declare -p vl; }
> declare -- vl="n"
> unicorn:~$ printf 'no\n' | { IFS='\n' read -r vl; declare -p vl; }
> declare -- vl="no"
> unicorn:~$ printf 'on\n' | { IFS='\n' read -r vl; declare -p vl; }
> declare -- vl="on"
> unicorn:~$ printf 'noon\n' | { IFS='\n' read -r vl; declare -p vl; }
> declare -- vl="noon"
> 
> THAT one behaves as I would expect.  It looks like the behavior
> changes between bash 3.0 and bash 3.1:
> 
> bash-3.0:
> declare -- vl="n"
> declare -- vl="no"
> declare -- vl="on"
> declare -- vl="noon"
> 
> bash-3.1:
> declare -- vl=""
> declare -- vl="no"
> declare -- vl="o"
> declare -- vl="noon"
> 
> This looks like a bug to me.  Either it strips trailing n's, or it doesn't,
> but in no case should it strip the trailing n only when the string is
> less then 4 characters long!

Nothing was stripped. Per 
https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_05,
 "IFS white space shall be ignored at the beginning and end of the input", with 
the definition being "any sequence of white-space characters that are in the 
IFS value". No white space characters were present in IFS, nor is "n" a white 
space character to begin with. It's also worth noting that consecutive 
instances of either "n" or "\" would never be treated as a single delimiter. 
That treatment is reserved for IFS white space characters.

> 
> unicorn:~$ printf 'non\n' | { IFS='\n' read -r vl; declare -p vl; } 
> declare -- vl="non"

This is similar to the second of your initial four test cases. Two fields are 
produced whose values are "" and "o". The difference is that the second field 
is properly terminated so the "remaining fields and their delimiters" verbiage 
accounts for the final "n" in the assigned value.

> unicorn:~$ printf 'bon\n' | { IFS='\n' read -r vl; declare -p vl; } 
> declare -- vl="bo"

This produces a single field whose value is "bo". It is all but identical to 
the third of your initial four test cases, the only difference being that the 
field happens to be two characters in length instead of one.

-- 
Kerin Millar



reply via email to

[Prev in Thread] Current Thread [Next in Thread]