[Top][All Lists]

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

Re: Syntax Question...

From: Linda Walsh
Subject: Re: Syntax Question...
Date: Thu, 18 Aug 2011 09:26:42 -0700
User-agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv: Gecko/20100228 Thunderbird/ Mnenhy/

` Greg Wooledge wrote:
On Thu, Aug 18, 2011 at 06:02:14AM -0700, Linda Walsh wrote:
The "shopt -s expand_aliases" feature has been in bash since I first
encountered it in ~1999.

Fine.  You know more bash bad practices than I do.  You win.
Just because you didn't know about it doesn't make it a bad practice.

It's like "-e" was very using in bash 3.0-4.0, but you didn't know it so
thought it worthless.

Just because you don't know about something doesn't make it worthless.

-eu has saved me countless of hours during devel before
I've added all the final error checking and killing a prog due
to a type-o that might otherwise have gone unnoticed for much longer.

I don't understand this... either it should be reporting an error, or
it should *not* be expanding the variable.  It doesn't seem to report
an error on multiple-file pathname expansions either:

   I don't think it expands the word immediately after the '<<<',
though the man page indicates it should do some expansion, but
expanding the value of a variable into separate words doesn't
seem to be one the explicitly mentioned cases...

   I thought it similar to $a not being expanded inside [[...]]

imadev:~$ read a <<< *.pdf
imadev:~$ echo "$a"

In fact, it's not even performing the expansion, as far as I can tell.
And yes, I have pathname expansion enabled (set +f) and I have several
*.pdf files in this directory.
   Now that one is suprising, as it's supposed to take the output of
the ... hmmm.....yup!...  that's exactly what it does.
takes the work and executes it and returns the results on stdin as
a single quoted blob of output:

   >  read a <<< *.txt
   >  echo $a
   apc_contact.txt .chklog.txt driver_filename.txt FFcookies.txt
   qb2.txt rcs_kywds-exmpls.txt return_rma.txt Soundtrack-II.txt
   Soundtrack-I.txt winsize.txt

But this is weird:

   { read a b c  } <<<*.txt  <<<*.dat  <<<*.log
   echo $a,  $b,  $c
   .bzr.log h.log q.log texput.log

i.e. the <<<*.txt and <<<*.dat are thrown away.

   Why?  Seems like a different way to do it, but why do you prefer it?

When you use <<< "$(...)" three [(x)un]desirable things happen.  The first
is that the entire command is executed all at once, and the script has
to wait for the entire process to finish.  The second is that all the
output is read into memory and stored, all at once.  The third is that
the stream is subtly altered: all trailing newlines are stripped by the
$(...) and then one newline is added by the <<<.
The first seems undesirable in most cases.
The second?  Eh... depends on the situation,

The third *may* be desirable*, as the case of:

   >  read a b c <<<$(echo "one"; echo "two"; echo "three"; echo $a, $b, $c
   one, two, three

vs. using < <():

   >  read a b c < <(echo "one"; echo "two"; echo "three"); echo $a, $b, $c
   one, ,

< <(...) by contrast runs the command in the background and reads from
it piecemeal.  So you get the stream's output as it's ready, a line at
a time, and unaltered.  It's probably not an important distinction in
this particular example, since your command only appears to produce one
line of output anyway, but in a loop it's a clear winner:

while read ...; do
done < <(some very long process)
But VERY good alternative to know when one wants a "reversed pipeline"...

i.e., one might normally use
(some ver long process) |while read do ....; done

But I understand the situations where you wouldn't want to
do that (i.e. being able to set 'shell' vars in the while loop, which would normally
get stuck in a a subshell and thus be unable to store into it's parent)...

normal pipe:

   >  (echo one; echo two; echo three)|while read x; do eval $x=$x;done
   >  echo $one, $two, $three
   , ,

vs. alternate w/ < <()

   >  while read x; do eval $x=$x; done < <(echo one; echo two; echo three)
   >  echo $one, $two, $three
   one, two, three

reply via email to

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