bug-bash
[Top][All Lists]
Advanced

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

Re: mapfile documentation


From: Greg Wooledge
Subject: Re: mapfile documentation
Date: Fri, 16 Mar 2018 14:59:53 -0400
User-agent: NeoMutt/20170113 (1.7.2)

You forgot to Cc: the mailing list.  I think this was on bug-bash...?

On Fri, Mar 16, 2018 at 02:06:09PM -0400, Boruch Baum wrote:
> On 2018-03-16 09:22, Greg Wooledge wrote:
> > On Fri, Mar 16, 2018 at 09:14:13AM -0400, Boruch Baum wrote:
> > > In GNU bash, version 4.4.18(1)-release (x86_64-pc-linux-gnu), the first
> > > line of the documentation for readarray / mapfile states:
> > >
> > >    Read lines from the standard input ...
> > >
> > > However, it doesn't seem to accept input from a pipe. It would be
> > > helpful to note that.
> >
> > It does.  What you're running into is the fact that each component of
> > the pipeline is run in a separate subshell, so any variables assignments
> > made during the pipeline (including read or mapfile) are lost once the
> > pipeline is completed.
> >
> > https://mywiki.wooledge.org/BashFAQ/024
> 
> I'm afraid what prompted me to file the report was something more
> subtle. Upon trying my test one-liner on a second virtual terminal, the
> one-liner worked, so I'm now trying to figure out what settings might
> affect the behavior. My test one-liner is:
> 
>       printf "aa bb\n cc\n" | readarray ; echo ${MAPFILE[0]}

First: https://mywiki.wooledge.org/Quotes

Second: how are you defining "Fail" and "Success"?  What result did
you get?  What result did you expect?  What was in this variable before
you ran your tests?

> Comparing the two bash instances:
> 
>                          FAIL   SUCCESS

> lastpipe                 off    off

(Note that lastpipe only works if job control is disabled.)

> I considered maybe IFS was set wrong, but that's not it
> 
>    echo $IFS |xxd
>    00000000: 0a

That is the single most spectacularly useless command I've seen in
quite a while.  A wonderful teaching example!  I should put it in
a quiz.  "What does this command print?  Why?  Why doesn't it matter
what the actual value of IFS is?"

Again: https://mywiki.wooledge.org/Quotes

This command will never reveal any information, period.  Every character
of IFS is guaranteed to be eaten by IFS splitting since you failed to
quote.  That's why echo receives no arguments, and only writes a single
newline to stdout.

Try this one instead:  printf %s "$IFS" | xxd

Or better still: printf %s "$IFS" | od -An -tx1

IFS will definitely affect the result of your unquoted MAPFILE expansion.
So don't use an unquoted ${MAPFILE[@]} either.  Quote properly.  Always.

> I then tried explicitly setting the delimiter using -d"\n", -d'\n' and
> -d\n, to no avail.

(What command did you run?  What output did you get?  What output did
you expect?)

> I've also tried changing the echo statement to "echo $? ${MAPfile[0]}",
> which returns just the zero.

https://mywiki.wooledge.org/Quotes

Also you misspelled MAPFILE.

>    type mapfile
>    mapfile is a shell builtin
> 
>    which mapfile ; echo $?
>    1

And now you know why you don't use which(1) for this.

> Any ideas?

Quote properly.  Show your actual results, and how you got them.
State your expected results.

wooledg:~$ echo hello world | (readarray; declare -p MAPFILE)
declare -a MAPFILE=([0]=$'hello world\n')

wooledg:~$ echo hello world | readarray
wooledg:~$ declare -p MAPFILE
bash: declare: MAPFILE: not found

wooledg:~$ shopt -s lastpipe
wooledg:~$ echo hello world | readarray; declare -p MAPFILE
bash: declare: MAPFILE: not found

wooledg:~$ set +m
wooledg:~$ echo hello world | readarray; declare -p MAPFILE
declare -a MAPFILE=([0]=$'hello world\n')

lastpipe will typically work in a script, because job control (set +m)
is disabled in scripts by default.  The reverse is true in an interactive
shell.



reply via email to

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