10

I often generate and register a lot of bash functions that automate many of the task I usually do in my development projects. That generation depends on the meta-data of the project I am working on.

I want to annotate the functions with the info of the project they were generated, this way:

func1() {
# This function was generated for project: PROJECT1
echo "do my automation"
}

Ideally, I would be able to see the comment when I inspect the definition:

$ type func1

func1 is a function
func1 () 
{
    # This function was generated for project: PROJECT1
    echo "do my automation"
}

But somehow bash seems to ignore the comments at the moment of loading the function, not when executing it. So the comments are lost and I get this result:

func1 is a function
func1 () 
{
    echo "do my automation"
}

Is there any way to assign metadata to functions, and check them afterwards? It is possible to retrieve it when inspecting the definition with type?

2

4 Answers 4

13
function func_name()
{
  : '
  Invocation:   func_name $1 $2 ... $n
  Function:     Display the values of the supplied arguments, in double quotes.
  Exit status:  func_name always returns with exit status 0.
  ' :
  local i
  echo "func_name: $# arguments"
  for ((i = 1; i <= $#; ++i)); do
    echo "func_name [$i] \"$1\""
    shift
  done
  return 0
}
2
  • 2
    hmmm, docstrings in bash. Who knew? Dec 9, 2016 at 20:23
  • Is there any way to query that comment? I thinking on a genery help function for all the commands.
    – yucer
    Mar 6, 2017 at 23:05
7

Yes, type seems to only print out the parts of a function that will be run. This seems reasonable to me, really, since usually that's all you are interested in when querying type.

As a workaround, instead of using comments, add your meta data like this:

func1() {
    meta="This function was generated for project: PROJECT1"
    echo "do my automation"
}

There's no need to ever actually use that variable, but it will appear when querying the function with type:

$ type func1
func1 is a function
func1 () 
{ 
    meta="This function was generated for project: PROJECT1";
    echo "do my automation"
}
2
  • 2
    If you want to avoid storing a variable, you can use the nop operator ":" this way: function func() { : "metadata" # do yours }
    – Luchostein
    Dec 9, 2016 at 15:01
  • 1
    I think single quotes are better than double quotes here, just in case there are any unwanted expansions hiding in the docstring Dec 9, 2016 at 22:05
6

You can use the nop builtin :. Besides, you don't need to store it as a variable:

function f() {
  : your metadata here
  : "or here"
  # do yours
}

EDIT: Beware of special characters into your metadata. For pure text, you can use:

: <<EOT
Your metadata text here.
EOT

EDIT: You may use instead a global associative array to store all function's metadata:

declare -A METADATA=()
METADATA[fun1]='foo bar'
function fun1() {
  echo I have some metadata: "${METADATA[$FUNCNAME]}"
}
METADATA[fun2]='baz you'
function fun2() {
  echo I have some other metadata: "${METADATA[$FUNCNAME]}"
}

This way, you don't need to parse declare or type's output, but only query for an array's key.

2
  • 1
    Be careful - your metadata here could contain expansions that have side-effects. Better to use single quotes like @AlexP's answer. Dec 9, 2016 at 22:06
  • Yes, but you should also be careful inside quotes.
    – Luchostein
    Dec 10, 2016 at 6:57
3

You can do this.

$ f() { This function does nothing. 2> /dev/null; }
$ f
$ type f
f is a function
f () 
{ 
    This function does nothing. 2> /dev/null
}
3
  • but the function should still do its stuff after being annotated. In the sample I'd included the echo should still work when i call the function normally.
    – yucer
    Dec 9, 2016 at 17:12
  • @yucer It would. This is just an illustration. Try it. It has its limitations though. No special characters like ( can be used and the first word shouldn't be a valid command.
    – user147505
    Dec 9, 2016 at 19:41
  • Ok. It think it is a valid answer, although it takes an extra time to run. Also it might be better to include the echo and the metadata that I'd used in my example.
    – yucer
    Dec 10, 2016 at 12:25

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .