attribuer et inspecter les métadonnées de la fonction bash


10

Je génère et enregistre souvent un grand nombre de fonctions bash qui automatisent la plupart des tâches que je fais habituellement dans mes projets de développement. Cette génération dépend des métadonnées du projet sur lequel je travaille.

Je veux annoter les fonctions avec les informations du projet qu'elles ont été générées, de cette façon:

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

Idéalement, je serais en mesure de voir le commentaire lorsque j'inspecterai la définition:

$ type func1

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

Mais bash semble ignorer les commentaires au moment du chargement de la fonction, pas lors de son exécution. Donc les commentaires sont perdus et j'obtiens ce résultat:

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

Existe-t-il un moyen d'affecter des métadonnées à des fonctions et de les vérifier ensuite? Il est possible de le récupérer lors de l'inspection de la définition avec le type?


1
Pas une solution (d'où le commentaire), mais la solution de contournement que j'utilise consiste à vérifier si $1c'est le cas -h, puis printf/ echoune aide / utilisation / sur une ligne.
John N

Réponses:


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
hmmm, docstrings en bash. Qui savait?
Brian Minton

Existe-t-il un moyen d'interroger ce commentaire? Je pense à une fonction d'aide genery pour toutes les commandes.
yucer

7

Oui, typesemble imprimer uniquement les parties d'une fonction qui seront exécutées. Cela me semble vraiment raisonnable, car c'est généralement tout ce qui vous intéresse lorsque vous interrogez type.

Pour contourner le problème, au lieu d'utiliser des commentaires, ajoutez vos métadonnées comme ceci:

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

Il n'est pas nécessaire d'utiliser réellement cette variable, mais elle apparaîtra lors de l'interrogation de la fonction avec type:

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

2
Si vous voulez éviter de stocker une variable, vous pouvez utiliser l'opérateur nop ":" de cette façon: function func () {: "metadata" # do yours}
Luchostein

1
Je pense que les guillemets simples sont meilleurs que les guillemets doubles ici, juste au cas où il y aurait des extensions indésirables se cachant dans la docstring
Digital Trauma

6

Vous pouvez utiliser le nop builtin :. De plus, vous n'avez pas besoin de le stocker en tant que variable:

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

EDIT : Méfiez-vous des caractères spéciaux dans vos métadonnées. Pour du texte pur, vous pouvez utiliser:

: <<EOT
Your metadata text here.
EOT

EDIT : Vous pouvez utiliser à la place un tableau associatif global pour stocker toutes les métadonnées de la fonction:

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 cette façon, vous n'avez pas besoin d'analyser declareou type« de la sortie, mais seulement pour la requête clé d'un tableau.


1
Soyez prudent - your metadata herepourrait contenir des extensions qui ont des effets secondaires. Mieux vaut utiliser des guillemets simples comme la réponse de @ AlexP.
Digital Trauma

Oui, mais vous devez également faire attention à l'intérieur des guillemets.
Luchostein

3

Tu peux le faire.

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

mais la fonction devrait toujours faire son travail après avoir été annotée. Dans l'exemple que j'avais inclus, l'écho devrait toujours fonctionner lorsque j'appelle la fonction normalement.
yucer

@yucer Ce serait le cas. Ceci n'est qu'une illustration. Essayez-le. Il a cependant ses limites. Aucun caractère spécial comme (ne peut être utilisé et le premier mot ne doit pas être une commande valide.

D'accord. Il pense que c'est une réponse valable, même si cela prend un temps supplémentaire pour s'exécuter. Il serait également préférable d'inclure l'écho et les métadonnées que j'avais utilisées dans mon exemple.
yucer
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.