Wie kann ich in meinem bashrc eine lokale Funktion erstellen?

40

Mein .bashrc hatte einen Code, der sich wiederholte, also benutzte ich eine Funktion, um ihn zu vereinfachen

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

do_stuff '5.1'
do_stuff '5.2'

Wenn ich jetzt jedoch meine Shell verwende, ist der Name "do_stuff" im Gültigkeitsbereich, sodass ich diese Funktion per Tab vervollständigen und ausführen kann (wodurch möglicherweise meine Umgebungsvariablen durcheinander gebracht werden). Gibt es eine Möglichkeit, "do_stuff" nur innerhalb der .bashrc sichtbar zu machen?

hugomg
quelle
2
Wenn Sie den Export nicht benötigen, können Sie auch ()eine Subshell erstellen. Eine andere Möglichkeit für einfache Fälle ist die Verwendung einer for version in 5.1 5.2Schleife, die jedoch versionentweichen kann.
Ciro Santilli

Antworten:

40

Verwenden Sie unsetals letzte Zeile in Ihrem .bashrc:

unset -f do_stuff

löscht / deaktiviert die Funktion do_stuff.

Um die Variablen zu löschen / zu deaktivieren, rufen Sie sie wie folgt auf:

unset variablename
Chaos
quelle
Ist unset wirklich der einzige Weg hierher? Nun, ich denke, wenn ich einen wirklich langen und hässlichen Namen für meine Funktion verwende, wird die Chance, dass er mit etwas anderem kollidiert, nicht so groß sein ...
hugomg
Wenn das das Problem Prüfung frist ist , wenn die Funktion vorhanden ist : if type do_stuff >/dev/null 2>&1; then echo "exists"; else echo "dont"; fi.
Chaos
8
Dies funktioniert nicht, wenn do_stuffes in einer anderen Funktion verwendet wird. Wenn Sie diese Funktion aufrufen, erhalten Sie bash: do_stuff: command not found. Ich weiß, dass dies nicht der genaue Fall ist, über den die Operation gesprochen hat, aber es lohnt sich darauf hinzuweisen.
Burhan Ali
Schön und POSIX .
Ciro Santilli 新疆 新疆 改造 法轮功 六四 六四
15

Die andere Möglichkeit besteht darin, Unterstriche wie in anderen Skriptsprachen zu verwenden, um anzuzeigen, dass diese Funktion nicht öffentlich sein soll. Die Wahrscheinlichkeit, dass Sie _do_foo eingeben, ist sehr gering und es ist unwahrscheinlich, dass Sie mit anderen in Konflikt geraten.

Sean Perry
quelle
1
Ja, verwenden Sie "_", um anzugeben, dass beabsichtigt ist, eine private Funktion zu übernehmen, dies hat jedoch nichts mit Konflikten zu tun. Jeder kann "_debug ()" oder "_safe_copy ()" benötigen. Wenn es etwas gibt, das hilft, Konflikte zu vermeiden, hat es nichts mit Unterstrichen zu tun .
Alois Mahdal
3

Die einzige Lösung, die ich mir vorstellen kann, ist, es zu unterstreichen und ihm einen ziemlich eindeutigen Namen zu geben, vielleicht sogar mit Punkten wie einer Fancypants-Sprache zu versehen ( aber das wird insh eurer alten Zeit nicht funktionieren ).

Heck, das wird keine Konflikte haben:

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

Wie in einem Kommentar vorgeschlagen, können Sie eine Unterschale verwenden:

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

Wir erstellen ein weiteres Skript auf der Subshell-Standardausgabe für den einzigen gewünschten Nebeneffekt (mithilfe von heredocument <<SIDE). Dann beziehen wir mit ..

Die Kraft von 'mise en abime' shist eine erschreckende Quelle des Staunens .

Champignac
quelle