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?

hugomg
la source
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
le chaos
la source
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
Nice et POSIX .
Ciro Santilli a annoncé le
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.

Sean Perry
la source
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")`; }
}
Camilo Martin
la source
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.

Champignac
la source