Jak mogę utworzyć lokalną funkcję w moim bashrc?

40

Mój .bashrc zawierał powtarzający się kod, więc użyłem funkcji, aby go uprościć

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

do_stuff '5.1'
do_stuff '5.2'

Jednak teraz, gdy używam mojej powłoki, nazwa „do_stuff” jest w zasięgu, więc mogę uzupełnić tabulatorami i uruchomić tę funkcję (potencjalnie psując moje zmienne środowiskowe). Czy istnieje sposób, aby „do_stuff” był widoczny tylko w .bashrc?

hugomg
źródło
2
Jeśli nie chcesz eksportować, możesz także użyć ()podpowłoki. Inną możliwością dla prostych przypadków jest użycie for version in 5.1 5.2pętli, chociaż pozwala to na versionucieczkę.
Ciro Santilli 9 改造 中心 法轮功 六四 事件

Odpowiedzi:

40

Użyj unsetjako ostatniej linii w .bashrc:

unset -f do_stuff

usunie / rozbroi funkcję do_stuff.

Aby usunąć / rozbroić zmienne, wywołaj je w następujący sposób:

unset variablename
chaos
źródło
Czy rozbicie jest naprawdę jedyną drogą tutaj? Cóż, myślę, że jeśli
użyję
Jeśli to check Frist problem, jeśli funkcja istnieje: if type do_stuff >/dev/null 2>&1; then echo "exists"; else echo "dont"; fi.
chaos
8
To nie zadziała, jeśli do_stuffzostanie użyte w innej funkcji. Po wywołaniu tej funkcji otrzymasz bash: do_stuff: command not found. Wiem, że nie jest to dokładnie ten przypadek, o którym mówiła operacja, ale warto to podkreślić.
Burhan Ali
Ładne i POSIX .
Ciro Santilli 新疆 改造 中心 法轮功 六四 事件
15

Inną opcją jest użycie podkreślników, takich jak w innych językach skryptowych, aby wskazać, że nie zamierzasz upubliczniać tej funkcji. Prawdopodobieństwo, że wpiszesz _do_foo, jest dość małe i mało prawdopodobne, aby powodowało konflikt z kimkolwiek innym.

Sean Perry
źródło
1
Tak, używaj „_”, aby wskazać zamiar posiadania funkcji prywatnej, ale nie ma to nic wspólnego z konfliktami. Każdy może potrzebować „_debug ()” lub „_safe_copy ()”. Jeśli jest coś, co pomaga uniknąć konfliktów, nie ma to nic wspólnego z podkreśleniami.
Alois Mahdal
3

Jedyne rozwiązanie, jakie mogę wymyślić, to podkreślenie go i nadanie mu dość unikalnej nazwy, może nawet przestrzeni nazw z kropkami jak wymyślny język ( ale to nie zadziała w waszych czasachsh ).

Cholera, nie będzie żadnych konfliktów:

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

Jak sugerowano w komentarzu, możesz użyć podpowłoki:

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

Budujemy kolejny skrypt na standardowym wyjściu podpowłoki dla jedynego pożądanego efektu ubocznego (używając heredokumentu <<SIDE). Następnie zaopatrujemy się w ..

Siła „mise en abime” shjest przerażającym źródłem cudów.

Champignac
źródło