How to do? Possible?

2011-07-25 Thread Linda Walsh



I got great help in learning about how to do the  perl equiv of (var1,
var2, var3)= (list) using read var1 var2 var3 <<<(list).

I use it often to get back lists of values from subroutine calls, but with
sometimes useful, and sometimes hindering fact that when I do
read var1 var2 var3 <<<$(function x y z)

function's ability to affect the global env, is 'nixed',

is there something like a
read var1 var2 var3 <<<${function x y z), that would do the same, but
like {} in code, wouldn't put the contents in a sub proc?


I can think of uglier looking ways to get around it, but was hoping
for something more elegant.

Truth be told, I split a file that was growing too large that had a mix
of functions and calls to them, by putting the functions into a separate
lib but I'd like the lib to be a bit more general and keep it's own state
(shared with the parent or not, wouldn't matter in my design), but as the
function calls are called in the (), there seems to be no easy way to
export them to anything that will be shared





Re: How to do? Possible?

2011-07-25 Thread Pierre Gaston
On Mon, Jul 25, 2011 at 12:20 PM, Linda Walsh  wrote:
>
>
>
> I got great help in learning about how to do the  perl equiv of (var1,
> var2, var3)= (list) using read var1 var2 var3 <<<(list).
>
> I use it often to get back lists of values from subroutine calls, but with
> sometimes useful, and sometimes hindering fact that when I do
> read var1 var2 var3 <<<$(function x y z)
>
> function's ability to affect the global env, is 'nixed',

Since  you are already using global variables, why not simply use a
couple more for the return values?



``complete -d -o default cd'' issue

2011-07-25 Thread Clark J. Wang
For example:

[bash-4.2.8] # ls -lF
total 4
drwxr-xr-x 3 root root 4096 2011-07-25 16:52 long-dir-name.d/
[bash-4.2.8] # ls -lF long-dir-name.d/
total 4
drwxr-xr-x 2 root root 4096 2011-07-25 16:52 bar/
[bash-4.2.8] # complete -d -o default cd
[bash-4.2.8] # cd *.d

Here the  cannot expand ``*.d'' to ``long-dir-name.d''. Bug?


Re: Built-in printf Sits Awkwardly with UDP.

2011-07-25 Thread Ralph Corderoy
Hi Chet,

> On 7/22/11 10:38 AM, Ralph Corderoy wrote:
> > On a related note, I can't interrupt this, e.g. Ctrl-C.
> > 
> > printf '%-92233720368547758q.\n' foo
> 
> That's interesting, since the fieldwidth (and precision) end up
> getting set to 0 if they overflow INT_MAX, at least on my machine, and
> the result is more or less instantaneous.  I agree that bash should do
> the same thing in printstr when presented with an overflowing field
> width that it does when using getint().  I will look at making that
> change.

I also get, with vanilla 4.2 built from source,

$ ./install/bin/bash -c "printf '%*q.\n' 10 foo -20 bar 0x8000"
   foo.
bar .
Segmentation fault (core dumped)
$ 

Cheers, Ralph.



Re: How to do? Possible?

2011-07-25 Thread Steven W. Orr

On 7/25/2011 5:20 AM, Linda Walsh wrote:




I got great help in learning about how to do the  perl equiv of (var1,
var2, var3)= (list) using read var1 var2 var3<<<(list).

I use it often to get back lists of values from subroutine calls, but with
sometimes useful, and sometimes hindering fact that when I do
read var1 var2 var3<<<$(function x y z)

function's ability to affect the global env, is 'nixed',

is there something like a
read var1 var2 var3<<<${function x y z), that would do the same, but
like {} in code, wouldn't put the contents in a sub proc?


I can think of uglier looking ways to get around it, but was hoping
for something more elegant.

Truth be told, I split a file that was growing too large that had a mix
of functions and calls to them, by putting the functions into a separate
lib but I'd like the lib to be a bit more general and keep it's own state
(shared with the parent or not, wouldn't matter in my design), but as the
function calls are called in the (), there seems to be no easy way to
export them to anything that will be shared




I highly recommend reading this, but read it *very carefully*. I have adopted 
this in my production system and it works great. The idea is to implement 
passing variables by reference and to allow the values to be either scalars or 
arrays. It sounds like you would benefit from this.


http://fvue.nl/wiki/Bash:_Passing_variables_by_reference

--
Time flies like the wind. Fruit flies like a banana. Stranger things have  .0.
happened but none stranger than this. Does your driver's license say Organ ..0
Donor?Black holes are where God divided by zero. Listen to me! We are all- 000
individuals! What if this weren't a hypothetical question?
steveo at syslang.net



Re: ``complete -d -o default cd'' issue

2011-07-25 Thread Andreas Schwab
"Clark J. Wang"  writes:

> Here the  cannot expand ``*.d'' to ``long-dir-name.d''. Bug?

You need to add -o bashdefault for that.

Andreas.

-- 
Andreas Schwab, sch...@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."



Re: How to do? Possible?

2011-07-25 Thread Linda Walsh
Pierre Gaston wrote:
> Since  you are already using global variables, why not simply use a
> couple more for the return values?
> 
--- 
Because a subshell cannot access the global variables of the
parent.

The only 'hack' I came up with overnight for a quick & dirty, is
to pass back a "blob" along with the 3 return values the function normally
returns, which the parent will 'eval' in the parent context (contain
'export XXX=value' or 'alias xxx=/path' statements.   The purpose of this
was to pre-verify the needed external utilities the script would be using
-- their paths and their existence so the script would be less likely to
fail non-deterministically later on.







Re: How to do? Possible?

2011-07-25 Thread DJ Mills
>        Because a subshell cannot access the global variables of the
> parent.
>

A subshell can access its parent's variables.  foo=bar; ( echo "$foo" )

A sub process cannot, unless the variables are exported.  It does not sound like
you need to do so here.



Re: How to do? Possible?

2011-07-25 Thread Linda Walsh


Steven W. Orr wrote:
> On 7/25/2011 5:20 AM, Linda Walsh wrote:
> I highly recommend reading this, but read it *very carefully*. I have
> adopted this in my production system and it works great. The idea is to
> implement passing variables by reference and to allow the values to be
> either scalars or arrays. It sounds like you would benefit from this.
> 
> http://fvue.nl/wiki/Bash:_Passing_variables_by_reference

Looks very interesting...will have to peruse it...
I'm starting to use eval more often -- generally haven't because
I thought it to be slow, but realistically, and as the article states,
with hard-timings, it's faster than expression in a sub-process...

That could lead to much more flexibility (besides benefit of speed).

Thanks!




Re: How to do? Possible?

2011-07-25 Thread Pierre Gaston
On Mon, Jul 25, 2011 at 8:33 PM, Linda Walsh  wrote:
> Pierre Gaston wrote:
>> Since  you are already using global variables, why not simply use a
>> couple more for the return values?
>>
> ---
>        Because a subshell cannot access the global variables of the
> parent.

uh?  you don't make sense.
1) a subshell can access  the parent variables just fine
2) your intial problem was to avoid the subshell of your solution to
be able to use global variables

I'm just saying : foo () {   ret1=blah;ret2=bleh; }; foo;echo $ret1 $ret2



Re: How to do? Possible?

2011-07-25 Thread Linda Walsh


DJ Mills wrote:
>> Because a subshell cannot access the global variables of the parent.
> 
> A subshell can access its parent's variables.  foo=bar; ( echo "$foo" )
> 
> A sub process cannot, unless the variables are exported.  It does not sound 
> like
> you need to do so here.

I'm not sure about your terminology -- a subshell is a subprocess.
By my understanding, "{}" defines a complex statement
and "()" defines both a subshell which is in a separate process, i.e.
subshell=sub process, but aside from 'symantic' issues, I didn't really
say fully what I meant -- you would have to read it in context of the previous
message where the idea was to 'set' the global vars in the subshell (not
in a complex statement) (ex. A, below)
OR be able use a complex statement in place of a subshell
after "<<<"
(ex. B, below)

Pierre Gaston wrote:
> On Mon, Jul 25, 2011 at 8:33 PM, Linda Walsh  wrote:
>> Pierre Gaston wrote:
>>> Since  you are already using global variables, why not simply use a
>>> couple more for the return values?
>>>
>> ---
>>Because a subshell cannot access the global variables of the
>> parent.
> 
> uh?  you don't make sense.
> 1) a subshell can access  the parent variables just fine
> 2) your intial problem was to avoid the subshell of your solution to
> be able to use global variables
> 
> I'm just saying : foo () {   ret1=blah;ret2=bleh; }; foo;echo $ret1 $ret2
> 

Arg:...
I'm hard to interpret, but, but that's cuz, gaston, ya got me confused
and off track, and I responded to what you said within the context of what
I was trying to do (set global variables in the function that also returned
values).

I had originally:
   A) read var1 var2 var3 <<<$(function a b c);

(where what I mean was function was the name of some random  function,
which I would hope could be gathered from syntax)

What I wished for was
   B) read var1 var var3 <<<${func a b c}

where I not only could have func pass back explicit return values,
but also, operate in the context of the parent, thus being able
to affect the parent's env vars.

The first form is the only form that works AFAIK,
the 2nd form is what I want to do ...


gaston replied:
Since  you are already using global variables, why not simply use a
couple more for the return values?
---
Ok, here's where things got confusing.   I gave A & B and you
responded with something that fell out of my example paradigm -- a function
returning explicit values, but also being able to effect the global ENV.

So I, first thing in the morning, I thought you were thought you were
asking "why not have $(function a b c) just return vals in 'global variables'"?
(which, I understand now, isn't what you meant).

That's why I responded that the subshell can't access [for purposes
of SETTING (*context*)), global vars...

So...now that that's all explained. there's still the original want...

(am still experimenting w/the 'pass-by-value stuff that DJMills referred to,
trying to flesh out a few more odd cases..., so of course I end up writing
a program to handle it all (got to complex doing all in interactively).

will keep you posted if you are interested...










bug? {1..3} doesnt' use IFS to separate fields

2011-07-25 Thread Linda Walsh


I know it wasn't designed this way, but it seems like it
is a bug.


If I do
  read a b c <<<$(echo {1..3} ); echo "a:$a b:$b c:$c"
I get:
  a:1 b:2 c:3

But If I do
  export IFS=','; read a b c <<<$(echo {1..3} ); echo "a:$a b:$b c:$c"
I get:
  a:1 2 3 b: c:

Why should the 2nd case return the wrong answer?
I.e. shouldn't {1..3} use the IFS to separate arguments?







Re: How to do? Possible?

2011-07-25 Thread Bob Proulx
Linda Walsh wrote:
> DJ Mills wrote:
> >> Because a subshell cannot access the global variables of the parent.
> > 
> > A subshell can access its parent's variables.  foo=bar; ( echo "$foo" )
> > 
> > A sub process cannot, unless the variables are exported.  It does
> > not sound like you need to do so here.
>
>   I'm not sure about your terminology -- a subshell is a
> subprocess.  By my understanding, "{}" defines a complex statement
> and "()" defines both a subshell which is in a separate process,

Yes, but it is a fork(2) of the parent shell and all of the variables
from the parent are copied along with the fork into the child process
and that includes non-exported variables.  Normally you would expect
that a subprocess wouldn't have access to parent shell variables
unless they were exported.  But with a subshell a copy of all
variables are available.

Bob



Re: How to do? Possible?

2011-07-25 Thread Linda Walsh


Bob Proulx wrote:
> Linda Walsh wrote:
>> DJ Mills wrote:
 Because a subshell cannot access the global variables of the parent.
>>> A subshell can access its parent's variables.  foo=bar; ( echo "$foo" )
>>>
>>> A sub process cannot, unless the variables are exported.  It does
>>> not sound like you need to do so here.
>>  I'm not sure about your terminology -- a subshell is a
>> subprocess.  By my understanding, "{}" defines a complex statement
>> and "()" defines both a subshell which is in a separate process,
> 
> Yes, but it is a fork(2) of the parent shell and all of the variables
> from the parent are copied along with the fork into the child process
> and that includes non-exported variables.  Normally you would expect
> that a subprocess wouldn't have access to parent shell variables
> unless they were exported.  But with a subshell a copy of all
> variables are available.
> 
> Bob
--

  Not really.
  It only seems that way because within () any "$" is usually
expanded BEFORE the () starts from the parent

  You can see this by
  GLOBAL="hi there"
  (echo $GLOBAL)
prints out "hi there" as expected, but if we hide
$GLOBAL so it isn't seen by parent:
(foo=GLOBAL; echo ${!foo})
prints ""

So, they aren't really available in a subshell, only
that a subshell's contents are evaluated before the subshell is
called.




Re: How to do? Possible?

2011-07-25 Thread Linda Walsh


Linda Walsh wrote:
> 
> Bob Proulx wrote:
>> Yes, but it is a fork(2) of the parent shell and all of the variables
>> from the parent are copied along with the fork into the child process
>> and that includes non-exported variables.  Normally you would expect
>> that a subprocess wouldn't have access to parent shell variables
>> unless they were exported.  But with a subshell a copy of all
>> variables are available.
>>
>> Bob
> --
>   Not really.
>   It only seems that way because within () any "$" is usually
> expanded BEFORE the () starts from the parent
> 
> You can see this by
>   GLOBAL="hi there"
>   (echo $GLOBAL)
> prints out "hi there" as expected, but if we hide
> $GLOBAL so it isn't seen by parent:
>   (foo=GLOBAL; echo ${!foo})
> prints ""
---
I mistyped that but it brings me to an interesting
conundrum:

GLOBAL="hi there"
{foo=GLOBAL echo ${!foo}; }

> (foo=GLOBAL echo ${!foo} )

But:
> { foo=GLOBAL;echo ${!foo}; }
hi there
> (foo=GLOBAL; echo ${!foo})
hi there
 
Weird...




Re: How to do? Possible?

2011-07-25 Thread Eric Blake

On 07/25/2011 03:45 PM, Linda Walsh wrote:

I mistyped that but it brings me to an interesting
conundrum:

GLOBAL="hi there"
{foo=GLOBAL echo ${!foo}; }


This says:

evaluate ${!foo}, and pass that expansion to 'echo', with foo=GLOBAL in 
the environment of echo.  You are invoking behavior that POSIX leaves 
undefined (that is, bash is perfectly fine evaluating ${!foo} prior to 
assigning foo, but bash would also be okay if it assigned foo prior to 
evaluating ${!foo}.  Hence, you got no output.



But:

{ foo=GLOBAL;echo ${!foo}; }

> hi there

The extra ; forces the semantics.  Here, the assignment to foo is a 
different statement than the expansion of of ${!foo}.  And while ${!foo} 
is a bash extension, it still proves that this is a case where foo was 
assigned prior to its use.



Weird...


Not if you think about it properly.

--
Eric Blake   ebl...@redhat.com+1-801-349-2682
Libvirt virtualization library http://libvirt.org



Re: How to do? Possible?

2011-07-25 Thread Davide Brini
On Mon, 25 Jul 2011 14:28:52 -0700, Linda Walsh  wrote:

>   Not really.
>   It only seems that way because within () any "$" is usually
> expanded BEFORE the () starts from the parent
> 
>   You can see this by
>   GLOBAL="hi there"
>   (echo $GLOBAL)
> prints out "hi there" as expected, but if we hide
> $GLOBAL so it isn't seen by parent:
> (foo=GLOBAL; echo ${!foo})
> prints ""
> 
> So, they aren't really available in a subshell, only
> that a subshell's contents are evaluated before the subshell is
> called.

There is a distinction to make between exported and non-exported variables.
Also, 

foo=bar command

is quite different from

foo=bar; command

(although sometimes, under certain conditions, they may appear to yield the
same result).

-- 
D.



Re: How to do? Possible?

2011-07-25 Thread Linda Walsh
Eric Blake wrote:
> On 07/25/2011 03:45 PM, Linda Walsh wrote:
>> I mistyped that but it brings me to an interesting
>> conundrum:
>>
>> GLOBAL="hi there"
>> {foo=GLOBAL echo ${!foo}; }
> 
> This says:
> 
> evaluate ${!foo}, and pass that expansion to 'echo', with foo=GLOBAL in
> the environment of echo.  You are invoking behavior that POSIX leaves
> undefined...
> 
>> Weird...
> 
> Not if you think about it properly.
---
Didn't think it was a bug. just 'odd', and that's because
it falls into a POSIX undefined case, that could really
go 'either way'...as you seemed to state.

I didn't know why it behaved differently, but as you informed me
the difference is 'one's well-defined, and the other is not, I can
see why there 'could' be a difference... ;-)

(which of course could change tomorrow, I suppose..)






Re: How to do? Possible?

2011-07-25 Thread Bob Proulx
Linda Walsh wrote:
> I didn't know why it behaved differently, but as you informed me
> the difference is 'one's well-defined, and the other is not, I can
> see why there 'could' be a difference... ;-)
> 
> (which of course could change tomorrow, I suppose..)

Not the second well defined case.  It can't change without being in
conflict with the standards.  You would always be safe to use it in
any standard conforming shell.

If you are still not convinced then consider these next two examples.

  #!/bin/sh
  printfoovar() { echo $foo ;}
  foo="bar"
  ( printfoovar )

  #!/bin/sh
  printfoovar() { eval echo \$$foo ;}
  bar="hello"
  foo="bar"
  ( printfoovar )

Bob



Re: How to do? Possible?

2011-07-25 Thread Dennis Williamson
On Mon, Jul 25, 2011 at 4:45 PM, Linda Walsh  wrote:
>
>
> Linda Walsh wrote:
>>
>> Bob Proulx wrote:
>>> Yes, but it is a fork(2) of the parent shell and all of the variables
>>> from the parent are copied along with the fork into the child process
>>> and that includes non-exported variables.  Normally you would expect
>>> that a subprocess wouldn't have access to parent shell variables
>>> unless they were exported.  But with a subshell a copy of all
>>> variables are available.
>>>
>>> Bob
>> --
>>   Not really.
>>   It only seems that way because within () any "$" is usually
>> expanded BEFORE the () starts from the parent
>>
>> You can see this by
>>   GLOBAL="hi there"
>>   (echo $GLOBAL)
>> prints out "hi there" as expected, but if we hide
>> $GLOBAL so it isn't seen by parent:
>>   (foo=GLOBAL; echo ${!foo})
>> prints ""
> ---
> I mistyped that but it brings me to an interesting
> conundrum:
>
> GLOBAL="hi there"
> {foo=GLOBAL echo ${!foo}; }
>
>> (foo=GLOBAL echo ${!foo} )
>
> But:
>> { foo=GLOBAL;echo ${!foo}; }
> hi there
>> (foo=GLOBAL; echo ${!foo})
> hi there
>  
> Weird...
>
>
>

I'm assuming you meant:

GLOBAL="hi there"
{foo=$GLOBAL echo ${!foo}; }

You had a missing dollar sign.

-- 
Visit serverfault.com to get your system administration questions answered.



Re: Built-in printf Sits Awkwardly with UDP.

2011-07-25 Thread Chet Ramey
On 7/25/11 8:49 AM, Ralph Corderoy wrote:

> I also get, with vanilla 4.2 built from source,
> 
> $ ./install/bin/bash -c "printf '%*q.\n' 10 foo -20 bar 0x8000"
>foo.
> bar .
> Segmentation fault (core dumped)
> $ 

Thanks for the report.  That's a different problem, caused by a missing
argument that printstr (via getint) doesn't handle very well.

Chet


-- 
``The lyf so short, the craft so long to lerne.'' - Chaucer
 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, ITS, CWRUc...@case.eduhttp://cnswww.cns.cwru.edu/~chet/



Re: ``complete -d -o default cd'' issue

2011-07-25 Thread Clark J. Wang
On Tue, Jul 26, 2011 at 12:00 AM, Andreas Schwab wrote:

> "Clark J. Wang"  writes:
>
> > Here the  cannot expand ``*.d'' to ``long-dir-name.d''. Bug?
>
> You need to add -o bashdefault for that.
>

``-o bashdefault'' works fine for me, thanks. But from the Bash manual I
think ``-o default'' should also work:

-o defaultUse readline's default filename completion if the compspec
generates no matches.

-Clark

>
> Andreas.
>
> --
> Andreas Schwab, sch...@linux-m68k.org
> GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
> "And now for something completely different."
>


Re: How to do? Possible?

2011-07-25 Thread Bob Proulx
Dennis Williamson wrote:
> Linda Walsh wrote:
> > GLOBAL="hi there"
> > {foo=GLOBAL echo ${!foo}; }

Note that this tickles a problem since foo isn't set before $foo is
expanded.  Use this following with a semicolon instead:

  GLOBAL="hi there"
  {foo=$GLOBAL; echo ${!foo}; }

> You had a missing dollar sign.
>
> I'm assuming you meant:
> 
> GLOBAL="hi there"
> {foo=$GLOBAL echo ${!foo}; }

Er..  No.  There is a missing semicolon as described above and in
other messages in the thread but the dollar size is intended to be
excluded so that foo contains the string "GLOBAL" and ${!foo} will
indirect through it.

The magic is the ${!parameter} syntax.  If you look at the bash
documentation for ${parameter} you will find the following
documentation.  The second paragraph explains the '!' part and is the
part needed to understand the indirection.

   ${parameter}
  The value of parameter is substituted.  The braces are
  required when parameter is a positional parameter with
  more than one digit, or when parameter is followed by a
  character which is not to be interpreted as part of its
  name.

   If the first character of parameter is an exclamation point
   (!), a level of variable indirection is introduced.  Bash uses
   the value of the variable formed from the rest of parameter as
   the name of the variable; this variable is then expanded and
   that value is used in the rest of the substitution, rather than
   the value of parameter itself.  This is known as indirect
   expansion.  The exceptions to this are the expansions of
   ${!prefix*} and ${!name[@]} described below.  The exclamation
   point must immediately follow the left brace in order to
   introduce indirection.

And so as you can see from this ${!foo} expands the value of foo to be
the string "GLOBAL" and then continues using that as an indirection
and expands the value of $GLOBAL.  With echo ${!foo} it would be very
similar to saying 'eval echo \$$foo'.  It would dynamically indirect
through and pick up the value of GLOBAL.

You can tell the difference by changing the value of GLOBAL between
echo statements.

Static direct binding:

  #!/bin/bash
  GLOBAL="one"
  foo=$GLOBAL
  { echo ${foo}; }
  GLOBAL="two"
  ( echo ${foo} )

Emits:

  one
  one

Dynamic indirect binding:

  #!/bin/bash
  GLOBAL="one"
  foo=GLOBAL
  { echo ${!foo}; }
  GLOBAL="two"
  ( echo ${!foo} )

Emits:

  one
  two

And the difference between using {...} and (...) is back to the
original discussion of the thread that subshells have access to
copies of all parent variables including variables that were not
explicitly exported.

Hope that helps to clarify things.

Bob



Re: How to do? Possible?

2011-07-25 Thread Dennis Williamson
Sorry, I overlooked the indirection (and the missing semicolon).

On Mon, Jul 25, 2011 at 10:18 PM, Bob Proulx  wrote:
> Dennis Williamson wrote:
>> Linda Walsh wrote:
>> > GLOBAL="hi there"
>> > {foo=GLOBAL echo ${!foo}; }
>
> Note that this tickles a problem since foo isn't set before $foo is
> expanded.  Use this following with a semicolon instead:
>
>  GLOBAL="hi there"
>  {foo=$GLOBAL; echo ${!foo}; }
>
>> You had a missing dollar sign.
>>
>> I'm assuming you meant:
>>
>> GLOBAL="hi there"
>> {foo=$GLOBAL echo ${!foo}; }
>
> Er..  No.  There is a missing semicolon as described above and in
> other messages in the thread but the dollar size is intended to be
> excluded so that foo contains the string "GLOBAL" and ${!foo} will
> indirect through it.
> . . .
> Bob
>



-- 
Visit serverfault.com to get your system administration questions answered.