hi! This is not a Debian problem. The bug, if at all there is one[1], is upstream and should be handled by the bash maintainer.
In some cases the return value of the unset builtin is inappropriate based on my reading of http://www.opengroup.org/onlinepubs/009695399/utilities/unset.html. unset name ... should return failure if any of name ... is not set. The comment about this not being an error says that a shell should not *abort* if this happens. i.e. unset valid_var1 nonexistent_var valid_var2 should unset valid_var1 and valid_var2. Instead of aborting when the shell notices nonexistent_var it should only return non-zero status. From www.opengroup.org/... EXIT STATUS 0 All name operands were successfully unset. >0 At least one name could not be unset. Somewhat related is unsetting of array variables. I think the exit status could be as follows a[1]=1;unset a a[1];echo ret=$? ret=1 a[1]=1;unset a[1] a;echo ret=$? ret=0 One thinks of unset a b c being done in the sequence a b c, and when the attempt to unbind is made, if there is an error the return status should indicate it[2]. Also, a[1]=2;unset a[2];echo ret=$? ret=0 This should be 1 since a has no element indexed by 2. I've attached two patches. patcha restores the bash-2.04 behaviour with respect to unset nonexistent_var. patchb makes unset ${a[nonexistentindex]} return non-zero. I may have upset the indentation of the source[3]. I have also added the correct quote about unset in the comments. Hope these help rather than end up seeming like an exercise in pedantry. I _actually_ look at the return status of unset when using bash interactively (I happen to use check_exit_status). Karthik P.S. - any_failed could also be returned as the exit status of unset. FOOTNOTES: 1. There is a changelog entry that documents this as a deliberate decision 2. Arrays needn't exist in shells AFAIK, so SUSv3 doesn't need to say anything about the sequence in which variables are unbound 3. Both spaces and tabs seem to be used. I tried duplicating this somewhat [end] -- There was a point to this story, but it has temporarily escaped the chronicler's mind. -- The Hitchhikers' Guide
diff -Naur bash-2.05b.orig/builtins/set.def bash-2.05b/builtins/set.def --- bash-2.05b.orig/builtins/set.def Wed Jul 10 20:17:20 2002 +++ bash-2.05b/builtins/set.def Thu Mar 10 23:02:46 2005 @@ -703,7 +703,10 @@ unset_builtin (list) WORD_LIST *list; { - int unset_function, unset_variable, unset_array, opt, any_failed; + int unset_function, unset_variable, opt, any_failed; +#if defined (ARRAY_VARS) + int unset_array; +#endif char *name; unset_function = unset_variable = unset_array = any_failed = 0; @@ -790,8 +793,6 @@ else { tem = unbind_array_element (var, t); - if (tem == -1) - any_failed++; } } else @@ -805,8 +806,14 @@ if (tem == -1 && !unset_function && !unset_variable) tem = unbind_func (name); + if (tem == -1) + any_failed++; + /* SUSv3, POSIX.1-2001 say: ``Unsetting a variable or function that was not previously set shall not be considered an error.'' */ + /* Actually SUSv3 says: ``Unsetting a variable or function that + * was not previously set shall not be considered an error and + * does not cause the shell to abort.'' */ if (unset_function == 0) stupidly_hack_special_variables (name);
diff -Naur bash-2.05b.orig/arrayfunc.c bash-2.05b/arrayfunc.c --- bash-2.05b.orig/arrayfunc.c Mon May 6 18:00:36 2002 +++ bash-2.05b/arrayfunc.c Thu Mar 10 23:04:34 2005 @@ -458,8 +458,11 @@ return -1; } ae = array_remove (array_cell (var), ind); - if (ae) + if (ae) { array_dispose_element (ae); + } else { + return (-1); + } return 0; }