3

Does the POSIX shell have something similar to $FUNCNAME in bash ?

Community
  • 1
  • 1
Andras P
  • 51
  • 7
  • Asking this because I normally use `do_something() { func=${FUNCNAME:-do_something} .... ; }` in my portable scripts and I was wondering if there is a simpler way maybe... – Andras P Oct 18 '15 at 20:40
  • Dup http://stackoverflow.com/q/2630812 – Zombo Oct 18 '15 at 20:48
  • Not really, the question there is '_The question: how do I get a list of all function names in a script from inside the script?_' not 'What is the current function name'. I am looking for a solution which looks like in bash `echo "Usage $FUNCNAME ".` – Andras P Oct 18 '15 at 20:54
  • Not that I know of. I think that's why bash added `$FUNCNAME` and I believe zsh uses `$0`. – Etan Reisner Oct 18 '15 at 21:04
  • This Bourne Shell? https://en.wikipedia.org/wiki/Bourne_shell . or the Bourne Again shell, more commonly known as `bash`? Good luck. – shellter Oct 19 '15 at 09:00
  • Lol, thanks for the heads up, completely forgot about this stuff. Corrected the post. – Andras P Oct 19 '15 at 21:38

2 Answers2

4

No. The list of variables which are required to have special behavior by the POSIX sh standard is quite small, and no equivalent to FUNCNAME is given; the closest thing is LINENO.

(If such a thing already existed in POSIX sh, why would bash have added its own rather than implementing the specification?)

Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
  • 1
    That was the question really: is it a bash specific stuff or do I miss something? Thanks for the answer – Andras P Oct 19 '15 at 22:07
  • 1
    @AndrasP It's bash specific. Ksh93 has an equivalent in `${.sh.fun}`. Try `function a { echo ".sh.fun=${.sh.fun}"; }`. You can make it emulate bash with `typeset -n FUNCNAME=.sh.fun`. By default, ksh tries not to overload shell variables with special behaviour. – Henk Langeveld Oct 20 '15 at 20:34
0

EDIT Just a note on how I tested if there is a variable that tells me what the current function is. What was confusing originally is FUNCNAME is available on Mac even in /bin/sh so I was wondering why it was empty on Linux - hence the OP. Opening the spec at variables shed some light on it (see accepted answer), but I was still curious what else is available in functions.

How to see the function related environment shell variables:

set shall write the names and values of all shell variables in the collation sequence of the current locale

So

$ set > a

$ function f() {
    set > b
}

$ f

Then

diff a b

Will give me function related variables in bash (and nothing in sh as expected)

> BASH_LINENO=([0]="5")
14a15
> FUNCNAME=([0]="f")
55c56
Andras P
  • 51
  • 7
  • As the POSIX spec. quotation shows, `set` without arguments should list _variables only_. It is a `bash`-specific _extension_ to also list _functions_ (If you run `bash` in POSIX mode (e.g., by running `shopt -so posix`), you'll get only variables). If using `bash` were an option, you could simply use `$FUNCNAME`. Truthfully, this answer is primarily a distraction - consider accepting @CharlesDuffy's answer. As an aside: the 'variables' link is about _environment_ variables, not _shell_ variables. – mklement0 Oct 19 '15 at 22:17
  • This was more of a side note on how can you find a variable that is related to the **current function**. Originally I was looking for a variable, so obviously I am using `set`. – Andras P Oct 20 '15 at 08:59
  • If this is a side note, please update this answer to clearly label it as such, and _explain how it relates to your question_. Also, the sentence "This also means that if I do the following I should get the information I needed" is especially confusing, given that the quote directly above clearly talks about shell _variables_ only. What I do find interesting is that you're implicitly demonstrating that POSIX-like shells do not create functions and variables until the line they're defined on is encountered during execution. – mklement0 Oct 20 '15 at 12:19
  • Thanks mklement0, this was is not really in context indeed, clarified. – Andras P Oct 20 '15 at 20:02
  • 2
    `/bin/sh` on many versions of MacOS is actually provided by bash (which runs in POSIX mode when so invoked, and so behaves *slightly* different from its original version, but is still a large superset). Testing its behavior doesn't tell you much. – Charles Duffy Oct 20 '15 at 20:32
  • 3
    `strings /bin/sh` is your friend, by the way, if you're looking for clues about who a specific implementation is / where it comes from. – Charles Duffy Oct 20 '15 at 20:34
  • `sh-3.2$ echo $SHELL` `/bin/bash` Yeah, that's true, I just _assumed_ I was in sh... Writing portable scripts make a whole different experience. Thanks for the heads up – Andras P Oct 20 '15 at 21:14
  • 1
    `$SHELL` just tells you what your _default_ shell is - irrespective of what shell you happen to be running at that time, so `echo $SHELL` doesn't tell you what you think it does. On some platforms, `sh` is just a _symlink_ to `bash`, but on OS X it is actually a _separate executable_ (still `bash` in drag, but with a few changes hard-compiled); once you've ruled out a simple symlink, `strings /bin/sh` is your friend, as @CharlesDuffy has stated. – mklement0 Oct 21 '15 at 02:32
  • _Environment_ variables aren't the same as _shell_ variables: all environment variables (which are independent of the shell) are also exposed as shell variables, but not all shell variables are also environment variables (they need to be _exported_ (`export`) for that). – mklement0 Oct 21 '15 at 02:34
  • There is no such thing as "function-related variables" in Bash; `set` also lists shell _functions_ (their full definitions) by default, which is an _extension_ to the POSIX standard. As a side-effect of Bash's execution model, functions only show up in the output of `set` once their _definition_ has been executed in the flow of normal execution, which is right after `f()`'s closing brace, actually (irrespective of whether `f` is later _called_ or not). – mklement0 Oct 21 '15 at 02:41
  • The lesson here is: if you target `sh`, assume POSIX features only - that's the only common denominator across platforms. – mklement0 Oct 21 '15 at 02:43
  • 1
    @mklement0 Thanks for your extremely useful comments – Andras P Oct 21 '15 at 09:02