Bug 407 - assign local vars and catch returncode
Summary: assign local vars and catch returncode
Status: RESOLVED WONTFIX
Alias: None
Product: Busybox
Classification: Unclassified
Component: Other (show other bugs)
Version: 1.13.x
Hardware: Other Linux
: P5 minor
Target Milestone: ---
Assignee: unassigned
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2009-06-19 13:05 UTC by Bastian Bittorf
Modified: 2009-06-20 16:19 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Bastian Bittorf 2009-06-19 13:05:39 UTC
OK:

myfunc ()
{
    VAR="$( return 1 )" || {
        some_error_trap
    }

    some_code
}


FAIL:

myfunc ()
{
    local VAR"$( return 1 )" || {
        some_error_trap
    }

    some_code
}

ofcourse 'return 1' means some action which
returns a returncode, but above code_snippet is a
good test. IMHO it should work, i see no reason
for not allowing that such style...(error_trap
is never reached in 2nd example)
Comment 1 Denys Vlasenko 2009-06-19 15:36:29 UTC
You example is unclear.

Do you mean something like this?

myfunc() { local VAR="$(false)" || { echo FAIL; }; echo DONE; }; myfunc

It does not print FAIL in bash either.


This does:

myfunc() { VAR="$(false)" || { echo FAIL; }; echo DONE; }; myfunc

I tested ash and hush and both match bash.
Comment 2 Bastian Bittorf 2009-06-20 10:41:01 UTC
> Do you mean something like this?
> 
> myfunc() { local VAR="$(false)" || { echo FAIL; }; echo DONE; }; myfunc

yes, if 'false' means:
an action, that produces a returncode != 0

> I tested ash and hush and both match bash.

You are right, but this means that bash and hush are
also affected - or is there a reason for "forgetting"
the returncode?
Comment 3 Bastian Bittorf 2009-06-20 10:46:42 UTC
to be more clear: 'false' and 'return 1' is
exactly the same in this example 8-)
Comment 4 Mike Frysinger 2009-06-20 11:13:46 UTC
what you're trying to do and what behavior you have a problem with still isnt clear.  instead of talking in pseudo code, post a small example of real code that isnt behavior the way you want.

f() { return 1; }
f
if [ $? -eq 1 ] ; then
  echo "this should be executed"
else
  echo "this should not be executed"
fi

the handling of local in hush should match bash because (1) local is not in POSIX so we have no official spec and (2) bash is the most widely used shell, so differing in behavior is just brain dead.
Comment 5 Bastian Bittorf 2009-06-20 11:46:59 UTC
> clear.  instead of talking in pseudo code, post a small example of real code

_phonebook_get ()
{
    local NAME="$1"
    local NUMBER

    # returns a valid phonenumber, if entry exists
    # otherwise returns false

    ...
}

_send_sms ()
{
    local DESTINATION="$1"
    local TEXT="$2"
    local PROVIDER="$( uci get system.service.sms.provider )"

    local NUMBER="$( _phonebook_get $DESTINATION )" || {
                         logger "user '$DESTINATION' unknown"
                         return 1
                 }

    _send_sms_$PROVIDER "$NUMBER" "$TEXT"
}

> the handling of local in hush should match bash because (1) local is not in
> POSIX so we have no official spec and (2) bash is the most widely used shell,
> so differing in behavior is just brain dead.

hmm, I understand your argument - but I still think, that BASH
is in this case not correctly implemented. Close the ticket, I
have to open a ticket @bug-bash....
Comment 6 Mike Frysinger 2009-06-20 15:47:02 UTC
then you need to bring it up on the bash lists.  if bash changes behavior, we'll change hush to match.

you can change your code easily by splitting the local and assignment in the mean time:
local foo
foo=$(false) || echo
Comment 7 Denys Vlasenko 2009-06-20 15:48:50 UTC
(In reply to comment #2)
> > Do you mean something like this?
> > 
> > myfunc() { local VAR="$(false)" || { echo FAIL; }; echo DONE; }; myfunc
> 
> yes, if 'false' means:
> an action, that produces a returncode != 0

No. 'false' is not something. Such command exists. It exits with exitcode 1.

My example was meant to be typed in at shell prompt literally, without any modifications. That's what good bug report should do: provide exact recipe to reproduce the bug. Yours wasn't exact.

> > I tested ash and hush and both match bash.
> 
> You are right, but this means that bash and hush are
> also affected - or is there a reason for "forgetting"
> the returncode?

First, if we match bash, it means we don't break scripts written for bash. This is good regardless of whether bash behavior is correct or not.

Second, who says it should be preserved?

"local a=b" is not the same as "a=b".

"local a=b" is running a builtin called "local". Every builtin has exitcode, just like normal commands. in this case it has exitcode 0: "I succeeded"

"a=b" is an assignment. It's not a command. It has no exitcode. IOW: exitcode of the last command is preserved across "a=b".
Comment 8 Denys Vlasenko 2009-06-20 15:52:39 UTC
BTW, it's not like we are lazy to fix this and looking for the excuses. The fix is very trivial. It's just I really don't think it's a bug.
Comment 9 Bastian Bittorf 2009-06-20 16:19:21 UTC
> "local a=b" is running a builtin called "local". Every builtin has exitcode,
> just like normal commands. in this case it has exitcode 0: "I succeeded"
> 
> "a=b" is an assignment. It's not a command. It has no exitcode. IOW: exitcode
> of the last command is preserved across "a=b".

That sounds correct and clear to me, ticket can be closed IMHO.
Thanks for your explanation.