7

I may have this function in a bash script that gets sourced to the shell

function suman{
     echo "using suman function"
}

if I call

unset suman

things seem to work as expected

however if I have this as my function:

function suman-inspect {
     echo "using suman-inspect function"
}

then if I call

unset suman-inspect

or

unset "suman-inspect"

I get this message:

bash: unset: `suman-inspect': not a valid identifier

How can unset this variable as is?

Alexander Mills
  • 90,741
  • 139
  • 482
  • 817

2 Answers2

6

After some more research, it appears that

unset -f "suman-inspect"

will work. This is surprising because unset suman did work, and did successfully unset the suman function (as far as I could tell).

Alexander Mills
  • 90,741
  • 139
  • 482
  • 817
  • 2
    +1 Fascinating! The documentation for `unset` says that "If no options are supplied, each *name* refers to a variable; if there is no variable by that name, any function with that name is unset." I'd have assumed that this would work even if the variable is not a valid variable-name, but apparently not! – ruakh Nov 25 '16 at 22:40
  • 2
    Probably what happens is that `unset` *assumes* that its argument (sans `-f`) is an identifier, but if no variable by that name exists, checks to see if you meant to unset a function instead. Only if you explicitly use `-f` does `bash` relax the "argument must be a valid identifier" rule. Quite a few `bash` extensions lack precisely documented descriptions of their semantics; some other examples include process substitution (e.g, where does `>(...)` inherit its standard *output* from?) and function exports (cf. ShellShock). – chepner Nov 29 '16 at 15:01
  • Does the hyphen/dash in suman-inspect make it an invalid identifier? – Alexander Mills Nov 29 '16 at 19:43
2

Bash allows functions with names which are not valid identifiers to be created when not in posix mode.

So:

set -o posix
function suman-inspect { echo "using suman-inspect function"; }

Gives:

bash: `suman-inspect': not a valid identifier

ruakh makes a valid point by quoting man bash. The source code (builtins/set.def) has the comment: Posix.2 says try variables first, then functions, but ...

The POSIX standard says If neither -f nor -v is specified, name refers to a variable; if a variable by that name does not exist, it is unspecified whether a function by that name, if any, shall be unset.

So actually the behaviour is that old standby "unspecified*. If anything, the error is in the bash documentation. But to be fair, elsewhere in man bash it says:

A function definition may be deleted using the -f option to the unset builtin.

Community
  • 1
  • 1
cdarke
  • 42,728
  • 8
  • 80
  • 84