asignar e inspeccionar metadatos de la función bash

10

A menudo genero y registro muchas funciones bash que automatizan muchas de las tareas que suelo realizar en mis proyectos de desarrollo. Esa generación depende de los metadatos del proyecto en el que estoy trabajando.

Quiero anotar las funciones con la información del proyecto que se generaron, de esta manera:

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

Idealmente, podría ver el comentario cuando inspeccione la definición:

$ type func1

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

Pero de alguna manera bash parece ignorar los comentarios en el momento de cargar la función, no al ejecutarla. Entonces los comentarios se pierden y obtengo este resultado:

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

¿Hay alguna forma de asignar metadatos a las funciones y verificarlas después? ¿Es posible recuperarlo al inspeccionar la definición con tipo?

platillo
fuente
1
No es una solución (de ahí el comentario), pero la solución que utilizo es verificar si $1es así -h, y luego printf/ echouna línea de ayuda / uso / lo que sea.
John N
2
Ver también: unix.stackexchange.com/questions/295022/…
Jeff Schaller

Respuestas:

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
}
AlexP
fuente
2
hmmm, docstrings en bash. ¿Quien sabe?
Brian Minton
¿Hay alguna forma de consultar ese comentario? Estoy pensando en una función de ayuda genery para todos los comandos.
platillo
7

Sí, typeparece que solo imprime las partes de una función que se ejecutará. Esto me parece razonable, realmente, ya que generalmente eso es todo lo que le interesa cuando realiza consultas type.

Como solución alternativa, en lugar de usar comentarios, agregue sus metadatos de esta manera:

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

No hay necesidad de usar esa variable, pero aparecerá al consultar la función con type:

$ type func1
func1 is a function
func1 () 
{ 
    meta="This function was generated for project: PROJECT1";
    echo "do my automation"
}
terdon
fuente
2
Si desea evitar almacenar una variable, puede usar el operador nop ":" de esta manera: function func () {: "metadata" # do yours}
Luchostein
1
Creo que las comillas simples son mejores que las comillas dobles aquí, en caso de que haya expansiones no deseadas escondidas en la cadena de documentos
Digital Trauma
6

Puedes usar el nop incorporado :. Además, no necesita almacenarlo como una variable:

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

EDITAR : tenga cuidado con los caracteres especiales en sus metadatos. Para texto puro, puede usar:

: <<EOT
Your metadata text here.
EOT

EDITAR : en su lugar, puede usar una matriz asociativa global para almacenar todos los metadatos de la función:

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]}"
}

De esta manera, no es necesario para analizar declareo typesalida 's, pero sólo consulta para la clave de una matriz.

Luchostein
fuente
1
Tenga cuidado, your metadata herepodría contener expansiones que tienen efectos secundarios. Es mejor usar comillas simples como la respuesta de @ AlexP.
Trauma digital
Sí, pero también debes tener cuidado con las comillas.
Luchostein
3

Puedes hacerlo.

$ f() { This function does nothing. 2> /dev/null; }
$ f
$ type f
f is a function
f () 
{ 
    This function does nothing. 2> /dev/null
}

fuente
pero la función aún debe hacer sus cosas después de ser anotada. En la muestra que había incluido, el eco aún debería funcionar cuando llamo a la función normalmente.
platillo
@yucer lo haría. Esto es solo una ilustración. Intentalo. Sin embargo, tiene sus limitaciones. No (se pueden usar caracteres especiales como y la primera palabra no debe ser un comando válido.
Okay. Piensa que es una respuesta válida, aunque toma un tiempo extra para ejecutarse. También podría ser mejor incluir el eco y los metadatos que había usado en mi ejemplo.
platillo