Question about the return value of 'local'

2012-12-13 Thread Francis Moreau
Hello,

I found that the return value of 'local' keyword is counter intuitive
when the value of the assignment is an expression returning false. In
that case the return value of local is still true. For example:

  local foo=$(echo bar; false)

returns true whereas:

  foo=$(echo bar; false)

returns false, that is removing the 'local' keyword has the opposite behaviour.

The help of 'local' is rather obscure about the description on its return value:

Returns success unless an invalid option is supplied, an
error occurs, or the shell is not executing a function.

"an error occurs" is rather meaningless IMHO.

Could anybody explain me why 'local' returns true in this case ?

Also I tried to find in the documentation, where the specification of
the return value of an asignment is but have failed. Could anybody
point me out the location ?

Thanks
--
Francis



Re: Question about the return value of 'local'

2012-12-13 Thread Bob Proulx
Francis Moreau wrote:
> I found that the return value of 'local' keyword is counter intuitive
> when the value of the assignment is an expression returning false. In
> that case the return value of local is still true. For example:
> 
>   local foo=$(echo bar; false)
> 
> returns true

Yes.  The creation of the local variable foo was successful.

> whereas:
> 
>   foo=$(echo bar; false)
> 
> returns false, that is removing the 'local' keyword has the opposite 
> behaviour.

The "local" function itself is either there or it isn't.  If it is
there then the return value is the return from local.  If it isn't
there then it isn't there and the return value is of whatever you are
checking.

If the local value is there then you may use it to assign multiple
values.  How does your thinking change when thinking about having
multiple values to local?

  local v1=true v2=false v3="green" v4=42

If the entire operation is successful then it returns 0.  If any of
the operands fail then it returns non-zero.

> The help of 'local' is rather obscure about the description on its return 
> value:
> 
> Returns success unless an invalid option is supplied, an
> error occurs, or the shell is not executing a function.
> 
> "an error occurs" is rather meaningless IMHO.
> 
> Could anybody explain me why 'local' returns true in this case ?

It returns 0 because the local variable was successfully created.

> Also I tried to find in the documentation, where the specification of
> the return value of an asignment is but have failed. Could anybody
> point me out the location ?

The bash manual contains this:

   local [option] [name[=value] ...]
  For each argument, a local variable named name is
  created, and assigned value.  The option can be any of
  the options accepted by declare.  When local is used
  within a function, it causes the variable name to have a
  visible scope restricted to that function and its
  children.  With no operands, local writes a list of
  local variables to the standard output.  It is an error
  to use local when not within a function.  The return
  status is 0 unless local is used outside a function, an
  invalid name is supplied, or name is a readonly
  variable.

See also 'export'.  Compare and contrast.

   export [-fn] [name[=word]] ...
   export -p
  The supplied names are marked for automatic export to
  the environment of subsequently executed commands.  If
  the -f option is given, the names refer to functions.
  If no names are given, or if the -p option is supplied,
  a list of all names that are exported in this shell is
  printed.  The -n option causes the export property to be
  removed from each name.  If a variable name is followed
  by =word, the value of the variable is set to word.
  export returns an exit status of 0 unless an invalid
  option is encountered, one of the names is not a valid
  shell variable name, or -f is supplied with a name that
  is not a function.

Bob



Re: Question about the return value of 'local'

2012-12-13 Thread Andreas Schwab
Francis Moreau  writes:

> The help of 'local' is rather obscure about the description on its return 
> value:
>
> Returns success unless an invalid option is supplied, an
> error occurs, or the shell is not executing a function.
>
> "an error occurs" is rather meaningless IMHO.

See the manual for an alternative description:

 The return status is zero unless `local' is used outside a
 function, an invalid NAME is supplied, or NAME is a readonly
 variable.

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: Question about the return value of 'local'

2012-12-13 Thread Francis Moreau
On Thu, Dec 13, 2012 at 9:44 AM, Bob Proulx  wrote:
> Francis Moreau wrote:
>> I found that the return value of 'local' keyword is counter intuitive
>> when the value of the assignment is an expression returning false. In
>> that case the return value of local is still true. For example:
>>
>>   local foo=$(echo bar; false)
>>
>> returns true
>
> Yes.  The creation of the local variable foo was successful.
>
>> whereas:
>>
>>   foo=$(echo bar; false)
>>
>> returns false, that is removing the 'local' keyword has the opposite 
>> behaviour.
>
> The "local" function itself is either there or it isn't.  If it is
> there then the return value is the return from local.  If it isn't
> there then it isn't there and the return value is of whatever you are
> checking.
>
> If the local value is there then you may use it to assign multiple
> values.  How does your thinking change when thinking about having
> multiple values to local?
>
>   local v1=true v2=false v3="green" v4=42
>
> If the entire operation is successful then it returns 0.  If any of
> the operands fail then it returns non-zero.

Ok I see, thanks.

>
>> The help of 'local' is rather obscure about the description on its return 
>> value:
>>
>> Returns success unless an invalid option is supplied, an
>> error occurs, or the shell is not executing a function.
>>
>> "an error occurs" is rather meaningless IMHO.
>>
>> Could anybody explain me why 'local' returns true in this case ?
>
> It returns 0 because the local variable was successfully created.
>
>> Also I tried to find in the documentation, where the specification of
>> the return value of an asignment is but have failed. Could anybody
>> point me out the location ?
>
> The bash manual contains this:
>
>local [option] [name[=value] ...]

Actually I was asking for the case when 'local' is not used:

  foo=$(echo bar; false)

this assignment expression returns false, and I'm wondering where
that's documented.

Thanks.
--
Francis



Re: Question about the return value of 'local'

2012-12-13 Thread Francis Moreau
On Thu, Dec 13, 2012 at 9:44 AM, Andreas Schwab  wrote:
> Francis Moreau  writes:
>
>> The help of 'local' is rather obscure about the description on its return 
>> value:
>>
>> Returns success unless an invalid option is supplied, an
>> error occurs, or the shell is not executing a function.
>>
>> "an error occurs" is rather meaningless IMHO.
>
> See the manual for an alternative description:
>
>  The return status is zero unless `local' is used outside a
>  function, an invalid NAME is supplied, or NAME is a readonly
>  variable.
>

I see thanks.

Somehow I thought that help(1) would have given nothing more nothing
less than what was described in the manual.

--
Francis



Re: Question about the return value of 'local'

2012-12-13 Thread Chet Ramey
On 12/13/12 3:56 AM, Francis Moreau wrote:

> I see thanks.
> 
> Somehow I thought that help(1) would have given nothing more nothing
> less than what was described in the manual.

`help' is a quick reference -- a handy shortcut.  The authoritative
documentation is still the manual page and texinfo document.  I'll
add something to the effect that `error' means `variable assignment
error'.

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: Question about the return value of 'local'

2012-12-13 Thread Chet Ramey
> Actually I was asking for the case when 'local' is not used:
> 
>   foo=$(echo bar; false)
> 
> this assignment expression returns false, and I'm wondering where
> that's documented.

Look in the SIMPLE COMMAND EXPANSION section of the man page:

   If  there is a command name left after expansion, execution proceeds as
   described below.  Otherwise, the command exits.  If one of  the  expan-
   sions  contained a command substitution, the exit status of the command
   is the exit status of the  last  command  substitution  performed.   If
   there were no command substitutions, the command exits with a status of
   zero.

It's the final paragraph.

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: Several issues with coprocesses regarding exit status

2012-12-13 Thread Chet Ramey
On 12/12/12 3:11 AM, Andreas Schwab wrote:

>>   To reproduce:
>> if ! coproc false; then echo error1 >&2; fi; wait "$COPROC_PID" || echo
>> error2 >&2
> 
> This has nothing to do with if but with ! which doesn't appear to work
> in this context.

Correct; good catch.  It was an oversight and will be fixed in the next
version.  It's interesting that nobody noticed it before now.

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: Several issues with coprocesses regarding exit status

2012-12-13 Thread DJ Mills
On Thu, Dec 13, 2012 at 2:32 PM, Chet Ramey  wrote:

> On 12/12/12 3:11 AM, Andreas Schwab wrote:
>
> >>   To reproduce:
> >> if ! coproc false; then echo error1 >&2; fi; wait "$COPROC_PID" ||
> echo
> >> error2 >&2
> >
> > This has nothing to do with if but with ! which doesn't appear to work
> > in this context.
>
> Correct; good catch.  It was an oversight and will be fixed in the next
> version.  It's interesting that nobody noticed it before now.
>
> Chet
>
>
> --
> ``The lyf so short, the craft so long to lerne.'' - Chaucer
>  ``Ars longa, vita brevis'' - Hippocrates
> Chet Ramey, ITS, CWRUc...@case.edu
> http://cnswww.cns.cwru.edu/~chet/
>

The issue with the NAME_PID variable as well?


Re: Several issues with coprocesses regarding exit status

2012-12-13 Thread Chet Ramey
On 12/11/12 2:31 PM, DJ Mills wrote:

The first two have been covered in other messages.

> 
> 3)
>   The first two issues aren't THAT big of a deal, because you can simply not
>   worry about coproc's exit status and use wait's.

That's the idea; the coproc command itself returns an indication of whether
or not the process to execute the command was created successfully.


> That leads me to the
> third
>   and largest issue, which is that "NAME_PID" only appears to work properly
>   either when in an interactive shell or when there's no command between the
>   coproc and the wait.

It's a race to see whether or not the coprocess exits and is reaped and
cleaned up before wait executes.  `false' is a very short-lived process,
doesn't require an exec, and so I would expect the child to exit very
quickly.  The cleanup, which includes unsetting the coproc-specific
variables, happens when the coprocess is reaped, not when the next one is
created.

You can avoid the error by using something like
[ -n "$COPROC_PID" ] && wait "$COPROC_PID"

but of course you lose the exit status that way.

I will look at saving the coprocess pids in the shell's list of exited
background jobs (or see whether they're being saved there already), so
if you manage to save the coproc pid you will be able to find the exit
status.

There are also some race conditions with coproc creation and very short-
lived processes; look at
http://lists.gnu.org/archive/html/bug-bash/2012-10/msg00027.html
for some additional details.

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/



shouldn't /+(??) capture 2 letter files only?

2012-12-13 Thread gregrwm
i wanted to move a bunch of files & directories, all except a certain
few, so i figured i'd use !(this|or|that).  so first i looked to see
if +(this|or|that) isolated what i expected.  well perhaps i don't
understand what it's supposed to do..  shouldn't /+(??) capture 2
letter files only?

$  echo /+()
/boot /home /proc /root /sbin
$  echo /+(???)
/bin /dev /etc /lib /mnt /opt /run /srv /sys /tmp /usr /var
$  echo /+(??)
/b1 /boot /c6 /e1 /home /initrd.img /lost+found /nu /pl /pm /proc /px
/ql /root /sbin

$  uname -a;apt-cache policy bash
Linux phovd 3.2.0-23-generic #36-Ubuntu SMP Tue Apr 10 20:41:14 UTC
2012 i686 athlon i386 GNU/Linux
bash:
  Installed: 4.2-2ubuntu2
  Candidate: 4.2-2ubuntu2
  Version table:
 *** 4.2-2ubuntu2 0
500 http://us.archive.ubuntu.com/ubuntu/ precise/main i386 Packages
100 /var/lib/dpkg/status



Re: shouldn't /+(??) capture 2 letter files only?

2012-12-13 Thread Dan Douglas
On Thursday, December 13, 2012 07:23:11 PM gregrwm wrote:
> i wanted to move a bunch of files & directories, all except a certain
> few, so i figured i'd use !(this|or|that).  so first i looked to see
> if +(this|or|that) isolated what i expected.  well perhaps i don't
> understand what it's supposed to do..  shouldn't /+(??) capture 2
> letter files only?
> 
> $  echo /+()
> /boot /home /proc /root /sbin
> $  echo /+(???)
> /bin /dev /etc /lib /mnt /opt /run /srv /sys /tmp /usr /var
> $  echo /+(??)
> /b1 /boot /c6 /e1 /home /initrd.img /lost+found /nu /pl /pm /proc /px
> /ql /root /sbin

The +() pattern is equivalent to ()+ in ERE. It means "one or more of any 
member of the pattern list". IMO "?" is more confusing because you'd probably 
guess that it means "zero or one" as in the regex quantifier, but it's 
actually the same as ".", meaning exactly one of anything.

So, +(??) actually matches strings with even length, while +(???) matches 
those with odd length. +(?) matches any string with at least one character, 
and any number of ?'s matches multiples of that length.

 $ ksh -c 'printf %R\\n \?'
^.$
 $ ksh -c 'printf %R\\n "+(?)"'
^(.)+$
 $ ksh -c 'printf %R\\n "+(??)"'
^(..)+$

-- 
Dan Douglas



Re: shouldn't /+(??) capture 2 letter files only?

2012-12-13 Thread Rene Herman

On 12/14/2012 02:23 AM, gregrwm wrote:


shouldn't /+(??) capture 2 letter files only?


No, that matches anything beginning with a slash, followed by one or
more groups of two characters. That is, followed by two characters, by 
4, 6, and so on. If you had any 6 or 8 (or 9, or 12, or...) then your 
first two examples would've shown the same behavior as your third. It 
seems you just want "/??"


Rene.



Re: shouldn't /+(??) capture 2 letter files only?

2012-12-13 Thread DJ Mills
On Thu, Dec 13, 2012 at 8:58 PM, Dan Douglas  wrote:

> So, +(??) actually matches strings with even length, while +(???) matches
> those with odd length. +(?) matches any string with at least one character,
> and any number of ?'s matches multiples of that length.
>
>  $ ksh -c 'printf %R\\n \?'
> ^.$
>  $ ksh -c 'printf %R\\n "+(?)"'
> ^(.)+$
>  $ ksh -c 'printf %R\\n "+(??)"'
> ^(..)+$
>
> --
> Dan Douglas
>
>
+(???) matches lengths that are multiples of 3, not all odd-length files.
?+(??) would match odd-length files.

For the original question, you would want /@(??) or simply /??, since
there's no need for extglob for that.


Re: Several issues with coprocesses regarding exit status

2012-12-13 Thread DJ Mills
On Thu, Dec 13, 2012 at 3:42 PM, Chet Ramey  wrote:

> It's a race to see whether or not the coprocess exits and is reaped and
> cleaned up before wait executes.  `false' is a very short-lived process,
> doesn't require an exec, and so I would expect the child to exit very
> quickly.  The cleanup, which includes unsetting the coproc-specific
> variables, happens when the coprocess is reaped, not when the next one is
> created.
>
> You can avoid the error by using something like
> [ -n "$COPROC_PID" ] && wait "$COPROC_PID"
>
> but of course you lose the exit status that way.
>
> I will look at saving the coprocess pids in the shell's list of exited
> background jobs (or see whether they're being saved there already), so
> if you manage to save the coproc pid you will be able to find the exit
> status.
>
> There are also some race conditions with coproc creation and very short-
> lived processes; look at
> http://lists.gnu.org/archive/html/bug-bash/2012-10/msg00027.html
> for some additional details.
>
> Chet
>
> --
> ``The lyf so short, the craft so long to lerne.'' - Chaucer
>  ``Ars longa, vita brevis'' - Hippocrates
> Chet Ramey, ITS, CWRUc...@case.edu
> http://cnswww.cns.cwru.edu/~chet/
>

Great, thanks for the clarification. The actual use case is as follows:

coproc cowout {  "${cower[@]}" --color=never -uq; }
while read -ru "${cowout[0]}" pkg; do
  targets+=("$pkg")
done

if ! wait "$cowout_PID"; then
  die "cower error"
fi

Again, the whole idea is to be able to both read the ouptut in the current
shell and check the exit status. A race condition shouldn't be an issue
there, obviously, since it's not going to exit until the loop finishes. So
with the change you suggested there, a simple: cower_pid=$cowout_PID #
before the while read loop should suffice.

Thanks again,
DJ


Re: shouldn't /+(??) capture 2 letter files only?

2012-12-13 Thread Dan Douglas
On Thursday, December 13, 2012 09:25:02 PM DJ Mills wrote:
> +(???) matches lengths that are multiples of 3, not all odd-length files.
> ?+(??) would match odd-length files.

My bad :)
-- 
Dan Douglas



Re: Question about the return value of 'local'

2012-12-13 Thread Francis Moreau
On Thu, Dec 13, 2012 at 3:25 PM, Chet Ramey  wrote:
>> Actually I was asking for the case when 'local' is not used:
>>
>>   foo=$(echo bar; false)
>>
>> this assignment expression returns false, and I'm wondering where
>> that's documented.
>
> Look in the SIMPLE COMMAND EXPANSION section of the man page:
>
>If  there is a command name left after expansion, execution proceeds as
>described below.  Otherwise, the command exits.  If one of  the  expan-
>sions  contained a command substitution, the exit status of the command
>is the exit status of the  last  command  substitution  performed.   If
>there were no command substitutions, the command exits with a status of
>zero.
>
> It's the final paragraph.
>

Thanks you.

--
Francis



Re: Question about the return value of 'local'

2012-12-13 Thread Francis Moreau
On Thu, Dec 13, 2012 at 3:19 PM, Chet Ramey  wrote:
> On 12/13/12 3:56 AM, Francis Moreau wrote:
>
>> I see thanks.
>>
>> Somehow I thought that help(1) would have given nothing more nothing
>> less than what was described in the manual.
>
> `help' is a quick reference -- a handy shortcut.  The authoritative
> documentation is still the manual page and texinfo document.

Then maybe an option should be added to 'local' to display the full
description that one can get from the manual, or maybe change the
behaviour of '-m' switch ?

Thanks.