Es gibt viele Funktionen, die in der Bash-Shell verwendet werden können. Ihre Definitionen können aufgelistet werden set
, aber wie kann man herausfinden, in welchen Dateien bestimmte benutzerdefinierte Funktionen definiert sind?
28
Antworten:
Aktivieren Sie das Debuggen. Aus dem Bash-Handbuch :
Beispiel:
Und in der Tat:
quelle
shopt -s extdebug; declare -Ff quote; shopt -u extdebug
.find_function()( shopt -s extdebug; declare -F "$@"; )
. Mit den Parens auf dem Funktionskörper wird es in einer Subshell ausgeführt, und die Änderung von shopts hat keine Auswirkungen auf den Aufrufer. Und das-f
scheint nicht nötig zu sein.Dies ist tatsächlich komplizierter als es zunächst erscheint. Welche Dateien von Ihrer Shell gelesen werden, hängt davon ab, welchen Shell-Typ Sie gerade ausführen. Ob es interaktiv ist oder nicht, ob es sich um eine Login- oder eine Nicht-Login-Shell handelt und welche Kombination der oben genannten. So durchsuchen Sie alle Standarddateien, die von den verschiedenen Shells gelesen werden können
$functionName
:Wenn dies nicht funktioniert, rufen Sie möglicherweise eine nicht standardmäßige Datei mit
.
oder ihrem Alias aufsource
. Um solche Fälle zu finden, führen Sie Folgendes aus:Das bedarf wahrscheinlich einer Erklärung. Das
-P
aktiviert Perl-kompatible reguläre Ausdrücke (PCRE), mit denen wir eine ausgefeiltere Regex-Syntax verwenden können. Speziell:(^|\s)
: Entspricht entweder dem Anfang einer Zeile (^
) oder dem Leerzeichen (\s
).(\.|source)\s+
: Entspricht entweder einem Literalzeichen.
(\.
) oder dem Wortsource
, jedoch nur, wenn auf dieses ein oder mehrere Leerzeichen folgen.Folgendes gibt mir auf meinem System:
Wie Sie jedoch sehen können, wird die gesamte übereinstimmende Zeile gedruckt. Was uns wirklich interessiert, ist die Liste der aufgerufenen Dateinamen, nicht die Zeile, die sie aufruft. Sie können diese mit diesem, komplizierteren, regulären Ausdruck erhalten:
Das
-h
Flag unterdrückt das Drucken der Dateinamen, bei denen eine Übereinstimmung gefunden wurde. Diesgrep
gilt standardmäßig, wenn Sie aufgefordert werden, mehrere Dateien zu durchsuchen. Das-o
bedeutet "nur den passenden Teil der Zeile drucken". Die zusätzlichen Dinge, die zum regulären Ausdruck hinzugefügt werden, sind:\K
: Ignoriere alles, was bis zu diesem Punkt gepasst hat. Dies ist ein PCRE-Trick, mit dem Sie einen komplexen regulären Ausdruck verwenden können, um Ihre Übereinstimmung zu finden, aber diesen übereinstimmenden Teil nicht einschließen, wenn Sie das grep--o
Flag verwenden.Auf meinem System wird der obige Befehl zurückgegeben:
Beachten Sie, dass ich zufällig
.
gefolgt von einem Leerzeichen benutze, das nicht für das Sourcing verwendet wird, aber das liegt daran, dass ich einen Alias habe, der eine andere Sprache aufruft, nicht Bash. Das ist es, was die seltsame$a*100/$c
und")\n"'
in der Ausgabe oben gibt. Das kann man aber ignorieren.Zum Schluss erfahren Sie, wie Sie all das zusammenfassen und in allen Standarddateien und allen Dateien, die Ihre Standarddateien beziehen, nach einem Funktionsnamen suchen :
Fügen Sie diese Zeilen zu Ihrer hinzu
~/.bashrc
und Sie können dann ausführen (ich verwendefooBar
als Beispiel einen Funktionsnamen):Zum Beispiel, wenn ich diese Zeile in meinem habe
~/.bashrc
:Und die Datei
~/a
ist:Ich sollte es finden mit:
quelle
+=
array+="foo"
die Zeichenfolgefoo
an das erste Element des Arrays anzuhängen?Das übliche
bash
Lesen von Punktdateien pro Benutzer ist~/.bashrc
. Es kann jedoch durchaus sein, dass andere Dateien als Quelle vorliegen. Ich möchte beispielsweise Aliase und Funktionen in separaten Dateien namens~/.bash_aliases
und aufbewahren~/.bash_functions
, was das Auffinden dieser Dateien erheblich erleichtert. Sie können die Suche.bashrc
nachsource
Befehlen mit:Sobald Sie die Liste der vom Benutzer erstellten Dateien haben, können Sie sie und den Benutzer
.bashrc
mit einem einzigengrep
Aufruf durchsuchen , z. B. nach der Funktionfoo
für mein Setup:quelle