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