¿Cómo puedo crear una función local en mi bashrc?

40

Mi .bashrc tenía un código repetitivo, así que usé una función para simplificarlo

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

do_stuff '5.1'
do_stuff '5.2'

Sin embargo, ahora cuando uso mi shell, el nombre "do_stuff" está dentro del alcance, por lo que puedo completar con pestañas y ejecutar esa función (potencialmente desordenando mis variables de entorno). ¿Hay alguna manera de hacer que "do_stuff" sea visible solo dentro del .bashrc?

hugomg
fuente
2
Si no necesita la exportación, también puede usar ()para hacer una subshell. Otra posibilidad para casos simples es usar un for version in 5.1 5.2bucle, aunque esto permite versionescapar.
Ciro Santilli 新疆 改造 中心 法轮功 六四 事件

Respuestas:

40

Use unsetcomo última línea en su .bashrc:

unset -f do_stuff

eliminará / desarmará la función do_stuff.

Para borrar / desarmar las variables, invoca de la siguiente manera:

unset variablename
caos
fuente
¿Desarmado es realmente la única forma aquí? Bueno, supongo que si uso un nombre muy largo y feo para mi función de la posibilidad de que choque con algo más no va a ser tan grande ...
hugomg
Si ese es el cheque Frist problema si existe la función: if type do_stuff >/dev/null 2>&1; then echo "exists"; else echo "dont"; fi.
caos
8
Esto no funcionará si do_stuffse usa dentro de otra función. Cuando llame a esa función, obtendrá bash: do_stuff: command not found. Sé que este no es el caso exacto del que hablaba el operador, pero vale la pena señalarlo.
Burhan Ali
Agradable y POSIX .
Ciro Santilli 新疆 改造 中心 法轮功 六四 事件
15

La otra opción es usar guiones bajos como en otros lenguajes de script para indicar que no tiene la intención de que esta función sea pública. La probabilidad de que escribas _do_foo es bastante pequeña y es poco probable que entre en conflicto con alguien más.

Sean Perry
fuente
1
Sí, use "_" para indicar la intención de tener una función privada, pero esto no tiene nada que ver con los conflictos. Cualquiera puede necesitar "_debug ()" o "_safe_copy ()". Si hay algo que ayuda a evitar conflictos, no tiene nada que ver con guiones bajos.
Alois Mahdal
3

La única solución que se me ocurre es subrayarlo y darle un nombre bastante único, tal vez incluso el espacio de nombres con puntos como un lenguaje elegante ( pero esto no funcionará en los viejos tiempossh ).

Diablos, esto no tendrá ningún conflicto:

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

Como se sugiere en un comentario, puede usar una subshell:

#!/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,'

Construimos otro script en la salida estándar de la subshell para el único efecto secundario que deseamos (usando el heredocumento <<SIDE). Luego nos abastecemos con ..

El poder de 'mise en abime' shes una fuente aterradora de asombro.

Champignac
fuente