Como posso criar uma função local no meu bashrc?

40

Meu .bashrc tinha algum código repetitivo, então usei uma função para simplificá-lo

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

do_stuff '5.1'
do_stuff '5.2'

No entanto, agora quando eu uso meu shell, o nome "do_stuff" está no escopo para que eu possa completar com tabulação e executar essa função (potencialmente atrapalhando minhas variáveis ​​de ambiente). Existe uma maneira de tornar "do_stuff" visível apenas dentro do .bashrc?

hugomg
fonte
2
Se você não precisou da exportação, também pode usar ()para criar um subshell. Outra possibilidade para casos simples é usar um for version in 5.1 5.2loop, embora isso permita versionescapar.
Ciro Santilli respondeu

Respostas:

40

Use unsetcomo última linha no seu .bashrc:

unset -f do_stuff

excluirá / desabilitará a função do_stuff.

Para excluir / desabilitar as variáveis, invoque-o da seguinte maneira:

unset variablename
caos
fonte
Não é realmente definido o único caminho até aqui? Bem, eu acho que se eu usar um nome muito longo e feio para minha função a chance de ele colidir com outra coisa não vai ser tão grande ...
hugomg
Se for esse o cheque Frist problema se a função existe: if type do_stuff >/dev/null 2>&1; then echo "exists"; else echo "dont"; fi.
caos
8
Isso não funcionará se do_stufffor usado dentro de outra função. Quando você chama essa função, você recebe bash: do_stuff: command not found. Sei que esse não é o caso exato em que a operação estava falando, mas vale a pena ressaltar.
precisa
Nice e POSIX .
Ciro Santilli escreveu:
15

A outra opção é usar sublinhados, como em outras linguagens de script, para indicar que você não pretende que essa função seja pública. A probabilidade de você digitar _do_foo é muito pequena e também não deve entrar em conflito com ninguém.

Sean Perry
fonte
11
Sim, use "_" para indicar a intenção de ter uma função privada, mas isso não tem nada a ver com conflitos. Qualquer pessoa pode precisar de "_debug ()" ou "_safe_copy ()". Se existe algo que ajuda a evitar conflitos, isso não tem nada a ver com sublinhados.
Alois Mahdal
3

A única solução em que consigo pensar é enfatizá-lo e dar a ele um nome bastante exclusivo, talvez até mesmo colocando-o com pontos como uma linguagem de fantasia ( mas isso não funcionará em vocêsh ).

Caramba, isso não terá conflitos:

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

Conforme sugerido em um comentário, você pode usar um 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,'

Criamos outro script na saída padrão do subshell para o único efeito colateral que desejamos (usando o heredocumento <<SIDE). Então nós fonte com ..

O poder da mise en abime shé uma fonte assustadora de admiração.

Champignac
fonte