Wie definiere ich eine Bash-Funktion im Sinne einer alten Definition neu?

13

Gibt es eine Möglichkeit, eine Bash-Funktion im Sinne ihrer alten Definition neu zu definieren? Zum Beispiel möchte ich der Präambel der Funktion den folgenden Codeblock hinzufügen command_not_found_handle ():

# Check if $1 is instead a bash variable and print value if it is
local VAL=$(eval echo \"\$$1\")
if [ -n "$VAL" ] && [ $# -eq 1 ]; then
    echo "$1=$VAL"
    return $?
fi

Es ist derzeit in /etc/profile.d/PackageKit.sh definiert und wird von Bash-Startskripten bereitgestellt.

Auf diese Weise kann ich den Wert einer Umgebungsvariablen an der Eingabeaufforderung abfragen, indem ich einfach den Variablennamen eingebe (sofern kein solcher Befehl mit diesem Namen vorhanden ist). z.B

user@hostname ~:$ LANG
LANG=en_AU.utf8

Ich weiß, dass ich die aktuelle Definition einfach kopieren und einfügen und meine eigenen Änderungen hinzufügen kann ~/.bashrc, aber ich suche nach einer eleganteren Methode, die die Wiederverwendung von Code beinhaltet.

Bessere Möglichkeiten zur Erreichung meines Ziels oder Verbesserungen / Erweiterungen des Codes werden ebenfalls geschätzt.

tmoschou
quelle
Wenn diese Frage besser für den Stackoverflow geeignet wäre, kann jemand darüber migrieren, ich weiß nicht wie.
tmoschou
3
Ich denke, dieser Beitrag auf Stack Overflow beantwortet Ihre Frage.
Mat
2
Stattdessen evalkönnen Sie die Indirektion verwenden:local VAL=$(echo ${!1})
Bis auf weiteres angehalten.

Antworten:

14

Sie können die aktuelle Definition der Funktion ausdrucken und sie dann in eine Funktionsdefinition in einer evalKlausel aufnehmen.

current_definition=$(declare -f command_not_found_handle)
current_definition=${current_definition#*\{}
current_definition=${current_definition%\}}
prefix_to_add=$(cat <<'EOF'
  # insert code here (no special quoting required)
EOF
)
suffix_to_add=$(cat <<'EOF'
  # insert code here (no special quoting required)
EOF
)
eval "command_not_found_handle () {
  $prefix_to_add
  $current_definition
  $suffix_to_add
}"

Ein weiterer Ansatz, den ich klarer finde, besteht darin, die ursprüngliche Funktion unter einem neuen Namen zu definieren und dies aus Ihrer Definition heraus aufzurufen. Dies funktioniert nur, wenn Sie nicht auf die lokalen Variablen der ursprünglichen Definition reagieren müssen.

eval "original_$(declare -f command_not_found_handle)"
command_not_found_handle () {
  
  original_command_not_found_handle
  
}
Gilles 'SO - hör auf böse zu sein'
quelle
1
Prost, es ist mir nie in den Sinn gekommen, hier-Dokumente zu verwenden, kein spezielles Zitat erforderlich. Ich glaube, ich bevorzuge Ihre erste Methode, die es einfacher macht, die gesamte Definition anzuzeigen declare -f, aber ich mag die Art und Weise, wie Sie die ursprüngliche Funktion umbenennen.
tmoschou
0

Danke @mat, @ dennis-williamson. Nachdem ich Ihre Kommentare gelesen habe, habe ich diese bekommen

eval 'command_not_found_handle () {

    local VAL=$(echo "${!1}")
    if [ -n "$VAL" ] && [ $# -eq 1 ]; then
            echo "$1=$VAL"
            return $?
    fi

    '$(declare -f command_not_found_handle |
    tail -n +3 | head -n -1)'
}'

Obwohl ich glaube, ich bevorzuge @Gilles-Lösung.

tmoschou
quelle