[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: printf '%s\n' "$@" versus <<< redirection
From: |
goncholden |
Subject: |
Re: printf '%s\n' "$@" versus <<< redirection |
Date: |
Sat, 18 Feb 2023 10:46:08 +0000 |
------- Original Message -------
On Saturday, February 18th, 2023 at 10:09 PM, Kerin Millar <kfm@plushkava.net>
wrote:
> On Sat, 18 Feb 2023 08:50:02 +0000
> goncholden goncholden@protonmail.com wrote:
>
> > I am using the following bash function
> >
> > theone ()
> > {
> > printf '%s\n' "$@" \
> > | while IFS="" read -r vl; do
> > ...
> > done
> > }
> >
> > I have also been looking at this second implementation
> >
> > theone ()
> > {
> > while IFS="" read -r vl; do
> > ...
> > done <<< "$@"
> > }
> >
> > But it occurs to me that the two are actually different. Using <<< means
> > reading from stdin,
> > which will not preserve the arguments, so special chars (like newline) may
> > cause troubles.
>
>
> Clearly, they do different things but the second sentence is confused.
> Firstly, the reason that incorporating a newline character into the values of
> any of the parameters might cause a problem is because read defaults to using
> the newline as a record (line) delimiter. That particular problem can be
> circumvented by using NUL as a delimiter instead. It serves as a safe
> delimiter because bash strings can never contain it.
>
> printf '%s\0' "$@" | while IFS= read -rd '' vl; do ...; done
>
> Secondly, and regarding your herestring example, "$@" normally expands to as
> many distinct words as there are positional parameters. However, a herestring
> always expects to consume just one word. In this case, bash chooses to handle
> the situation by joining the positional parameters with the space character,
> producing that word. Should you ever genuinely want to do this, it would make
> more sense to write "$", in which case the parameters are joined by the first
> character of IFS (by default, a space). The behaviour of "$" is always the
> same, no matter the context in which it is used. Therefore, it would better
> indicate to the reader that the intention to join the parameters is
> deliberate.
>
> A better analogue of the first shown function would have involved the use of
> a process substitution, which is another way of setting up a pipe.
>
> while IFS= read -r vl; do ...; done < <(printf '%s\n' "$@")
>
> Still, I can only assume that the first example is academic in nature,
> because a simple for loop ought to be used instead.
>
> for vl in "$@"; do ...; done
I am not convinced that tho loop is equivalent to the first example.
My intention is to use prinf line by line on arguments containing newlines.
With a newline also introduced between arguments $1 $2 $3 etc.
> > The first implementation honours newlines in the arguments, whilst also
> > introduces a newline
> > between arguments (between $1, $2, $3, etc). Am I missing anything in my
> > analysis ?
>
>
> Apart from that which has been stated above, a herestring always used to
> result in the creation of a temporary file. This behaviour changed with the
> release of 5.1. Now, bash may choose to handle a herestring by internally
> creating a pipe, provided that the length of the word is within the limit
> defined by PIPE_BUF. Taking Linux as an example, the default pipe buffer size
> is 16 times the platform's page size. For an x86_64 system, that would amount
> to 64 KiB.
>
> $ declare -p BASH_VERSION
> declare -- BASH_VERSION="5.1.16(1)-release"
> $ readlink /proc/self/fd/0 <<<"$(printf %65535s)" # off-by-one because
> herestrings add a newline
> pipe:[1276109]
> $ readlink /proc/self/fd/0 <<<"$(printf %65536s)" # ditto
> /tmp/sh-thd.zpxDpj (deleted)
>
> --
> Kerin Millar
- printf '%s\n' "$@" versus <<< redirection, goncholden, 2023/02/18
- Re: printf '%s\n' "$@" versus <<< redirection, Kerin Millar, 2023/02/18
- Re: printf '%s\n' "$@" versus <<< redirection,
goncholden <=
- 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, goncholden, 2023/02/19
- Re: printf '%s\n' "$@" versus <<< redirection, Kerin Millar, 2023/02/19
Re: printf '%s\n' "$@" versus <<< redirection, alex xmb ratchev, 2023/02/18