[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
- Re: printf '%s\n' "$@" versus <<< redirection, (continued)
Re: printf '%s\n' "$@" versus <<< redirection, alex xmb ratchev, 2023/02/18
- Re: printf '%s\n' "$@" versus <<< redirection, Kerin Millar, 2023/02/18
- Re: printf '%s\n' "$@" versus <<< redirection, alex xmb ratchev, 2023/02/18
- Re: printf '%s\n' "$@" versus <<< redirection, Mike Jonkmans, 2023/02/18
- Re: printf '%s\n' "$@" versus <<< redirection, Kerin Millar, 2023/02/18
- Re: printf '%s\n' "$@" versus <<< redirection, goncholden, 2023/02/19
- Re: printf '%s\n' "$@" versus <<< redirection, Kerin Millar, 2023/02/19
- Re: printf '%s\n' "$@" versus <<< redirection, Greg Wooledge, 2023/02/19
- Re: printf '%s\n' "$@" versus <<< redirection,
Kerin Millar <=
- Re: printf '%s\n' "$@" versus <<< redirection, Greg Wooledge, 2023/02/19
- Re: printf '%s\n' "$@" versus <<< redirection, Kerin Millar, 2023/02/19
Re: printf '%s\n' "$@" versus <<< redirection, Greg Wooledge, 2023/02/19
Re: printf '%s\n' "$@" versus <<< redirection, goncholden, 2023/02/20
Re: printf '%s\n' "$@" versus <<< redirection, Greg Wooledge, 2023/02/20
Re: printf '%s\n' "$@" versus <<< redirection, goncholden, 2023/02/20
Re: printf '%s\n' "$@" versus <<< redirection, Chet Ramey, 2023/02/20
Re: printf '%s\n' "$@" versus <<< redirection, Mike Jonkmans, 2023/02/20
Re: printf '%s\n' "$@" versus <<< redirection, Greg Wooledge, 2023/02/20
Re: printf '%s\n' "$@" versus <<< redirection, Mike Jonkmans, 2023/02/21