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;
 }
 

Reply via email to