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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.