Comment créer une fonction locale dans mon répertoire?


40

Mon .bashrc avait du code qui était répétitif alors j'ai utilisé une fonction pour le simplifier

do_stuff() {
  local version=$1
  export FOO_${version}_X="17"
  export FOO_${version}_Y="42"
}

do_stuff '5.1'
do_stuff '5.2'

Cependant, maintenant, lorsque j'utilise mon shell, le nom "do_stuff" est dans la portée, ce qui me permet de compléter la tabulation et d'exécuter cette fonction (ce qui risquerait de gâcher mes variables d'environnement). Existe-t-il un moyen de rendre "do_stuff" visible uniquement à l'intérieur du fichier .bashrc?


2
Si vous n'avez pas exporté, vous pouvez également ()créer un sous-shell. Une autre possibilité pour les cas simples est d'utiliser une for version in 5.1 5.2boucle, bien que cela permette de versions'échapper.
Ciro Santilli a annoncé le

Réponses:


40

Utilisez unsetcomme dernière ligne de votre .bashrc:

unset -f do_stuff

supprime / annule la fonction do_stuff.

Pour supprimer / supprimer les variables, appelez-la comme suit:

unset variablename

Est-ce vraiment désarmé le seul moyen ici? Eh bien, je suppose que si j'utilise un nom vraiment long et moche pour ma fonction, la chance qu'elle se heurte à autre chose ne sera pas si grande ...
hugomg

Si tel est le problème vérification Frist si la fonction existe: if type do_stuff >/dev/null 2>&1; then echo "exists"; else echo "dont"; fi.
chaos

8
Cela ne fonctionnera pas si do_stuffest utilisé dans une autre fonction. Lorsque vous appelez cette fonction, vous obtiendrez bash: do_stuff: command not found. Je sais que ce n’est pas le cas exact dont l’opération parlait, mais cela vaut la peine d’être souligné.
Burhan Ali


15

L'autre option consiste à utiliser des traits de soulignement, comme dans d'autres langages de script, pour indiquer que vous ne souhaitez pas que cette fonction soit publique. La probabilité que vous tapiez _do_foo soit assez petite et aussi peu susceptible d'entrer en conflit avec quelqu'un d'autre.


1
Oui, utilisez "_" pour indiquer votre intention d'avoir une fonction privée, mais cela n'a rien à voir avec des conflits. Tout le monde peut avoir besoin de "_debug ()" ou "_safe_copy ()". S'il y a quelque chose qui aide à éviter les conflits, cela n'a rien à voir avec les soulignés.
Alois Mahdal

3

La seule solution à laquelle je peux penser est de le souligner et de lui donner un nom assez unique, peut-être même en le faisant ressortir avec des points comme un langage fantasmagorique ( mais cela ne fonctionnera pas dans les temps ancienssh ).

Heck, cela n'aura aucun conflit:

_my_foobar_method_91a3b52d990f4a9f9d5d9423ec37b64c () {
    # Custom proprietary logic protected ID 10 T intellectual property copyright clauses.
    cat <<< `echo $(xargs printf <<< "$1")`; }
}

0

Comme suggéré dans un commentaire, vous pouvez utiliser un sous-shell:

#!/bin/bash

. <(
  do_stuff() {
    local version="$1" valid='^\w+$'

    [[ "$version" =~ $valid ]] &&
      cat <<SIDE               || echo "$FUNCNAME: invalid '$version'" >&2
export FOO_${version}_X=17
export FOO_${version}_Y=42
SIDE
  }

  do_stuff 5.0 # FOO_5.0_X is "not a valid identifier"
  do_stuff 5_1
  do_stuff 5_2
)

do_keep() { :; } # just get sure the report below actually works

set | egrep '(do_|FOO_)' |  sed -e 's,^,set:\x09,'

Nous construisons un autre script sur la sortie standard du sous-shell pour le seul effet secondaire souhaité (utilisation de heredocument <<SIDE). Ensuite, nous source avec ..

Le pouvoir de la mise en abime shest une source d'émerveillement effrayante.

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.