0

Why does the builtin BASH command set print shell functions? My searches on Google, and even Stack Overflow, haven't produced a satisfactory answer. From the manual page, "Without options, the name and value of each shell variable are displayed ... ." With options doesn't change this. Functions aren't variables ... are they?

For reference, this became a problem when I was using set to test for the existence of a variable:

set_version() {
    if [[ ! $(set | grep -q PKG_VERSION_STAMP) ]]; then
        echo Version not set.  Using default
        PKG_VERSION_STAMP=0.1
    fi
    echo Package Version: $PKG_VERSION_STAMP
}

I tested the conditional construction from the interactive shell, and it worked, but that's because I hadn't defined it in a function. My script failed because the function was defined and the grep passed. Consequently, the variable, PKG_VERSION_STAMP, was never defined.

Incidentally, changing from set to env fixes the problem. I'd just like to know why BASH considers functions to be variables and print their contents.

Andrew Falanga
  • 2,274
  • 4
  • 26
  • 51
  • 3
    That's not a good way to test for the presence of a variable. Much better to just test for it having a value (and/or being null) with the `:-` [expansion](http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_02). Or Use `:=` to assign it a value when one doesn't already exist. I can't find anything about why `set` shows variables in the spec. I wonder if non-bash shells do that. – Etan Reisner Oct 27 '15 at 21:34
  • @EtanReisner wow thank you. I hadn't read, or known, of those expansions before now. That's very helpful. – Andrew Falanga Oct 27 '15 at 21:37
  • The question rather is: why should it not? The implementation of the shell functions is quite similar to the shell variables which are also shown using `set`. Introducing another built-in command (similar to `set`) for showing the shell functions would have no real advantage. – Alfe Oct 27 '15 at 21:43

1 Answers1

1

Should you want to have the set builtin not listing the shell functions, you can switch to bash posix mode:

$ set -o posix
$ set
...

While not documented in its manual, it is a well known fact since the shellshock vulnerability exposition that bash is storing its functions as special variables.

Community
  • 1
  • 1
jlliagre
  • 29,783
  • 6
  • 61
  • 72
  • Interesting. I've not heard of this bug and certainly didn't stumble across it while looking for an answer to my question (which I did do before posting the question). Thanks a lot for this. This is also from the manual page, "In posix mode, only shell variables are listed." However, the manual page specifically states, beforehand, that this builtin **only lists** shell variables and their values. – Andrew Falanga Oct 28 '15 at 16:39