Ich habe dieses nervige Problem in meiner ZSH-Shell, wo irgendwo eine Funktion deklariert wird und diese Funktion den Namen „cp“ trägt, sodass sie das normale cp-Verhalten überschreibt. Ich versuche, die Funktionsdeklaration zu finden, kann es aber nicht. Ich habe bereits an den normalen Stellen von .zshrc und den verschiedenen anderen Quellen gesucht, die in .zshrc enthalten sind, aber bisher nichts.
Andere Dinge, die ich versucht habe:
grep -r 'function cp' .
(von ~)whence -f cp
(gibt die Funktionsdefinition an, aber nicht, woher sie deklariert wurde)
Irgendwelche Ideen?
Antwort1
Erstens kann eine Funktion ohne das function
Schlüsselwort definiert werden, so dass eine bessere Suche wäre
grep 'cp()' .*
.zshrc
Dadurch werden Dateien wie und und so weiter durchsucht .profile
. Wenn dabei nichts gefunden wird, möchten Sie vielleicht auch die verschiedenen von geladenen Dateien sehen zsh
. Diese sind ganz am Ende von aufgeführt man zsh
:
FILES
$ZDOTDIR/.zshenv
$ZDOTDIR/.zprofile
$ZDOTDIR/.zshrc
$ZDOTDIR/.zlogin
$ZDOTDIR/.zlogout
${TMPPREFIX}* (default is /tmp/zsh*)
/etc/zsh/zshenv
/etc/zsh/zprofile
/etc/zsh/zshrc
/etc/zsh/zlogin
/etc/zsh/zlogout (installation-specific - /etc is the default)
Standardmäßig $ZDOTDIR
sollte es Ihre sein $HOME
. Dieser Befehl sollte also Ihre fehlerhafte Datei finden:
grep 'cp()\|cp ()' ~/.zshenv ~/.zprofile ~/.zshrc ~/.zlogin /etc/zsh/zshenv \
/etc/zsh/zprofile /etc/zsh/zshrc /etc/zsh/zlogin
Ich habe das hinzugefügt, \|
da zwischen dem Funktionsnamen und der Funktion selbst auch Leerzeichen stehen können. Schließlich@Dennis weist darauf hindass die Klammern auch weggelassen werden können, wenn Sie das function
Schlüsselwort verwenden. Um noch sicherer zu sein, gehen Sie folgendermaßen vor:
grep -E 'function cp|cp *\(\)' ~/.zshenv ~/.zprofile ~/.zshrc ~/.zlogin \
/etc/zsh/zshenv /etc/zsh/zprofile /etc/zsh/zshrc /etc/zsh/zlogin
Antwort2
Ich musste dies heute tun und habe festgestellt, dass whence -v
die Datei mit der Funktionsdefinition ausgegeben wird.
$ whence -v function_name
function_name is a shell function from /path/to/file
Antwort3
Neuere Versionen von zsh (seit 5.4, hinzugefügt im Commit34f70c5
) unterstützt das $functions_source
Array als Teil des zsh/parameter
Moduls (Dokumentation: man zshmodules
):
functions_source
Dieses schreibgeschützte assoziative Array ordnet die Namen aktivierter Funktionen dem Namen der Datei zu, die die Quelle der Funktion enthält.
Für eine automatisch geladene Funktion, die bereits geladen wurde oder mit einem absoluten Pfad zum automatischen Laden markiert wurde, oder deren Pfad mit „ “ aufgelöst wurde
functions -r
, ist dies die zum automatischen Laden gefundene und in einen absoluten Pfad aufgelöste Datei.Für eine Funktion, die im Hauptteil eines Skripts oder einer Quelldatei definiert ist, ist dies der Name dieser Datei. In diesem Fall ist dies der genaue Pfad, der ursprünglich zu dieser Datei verwendet wurde. Dabei kann es sich um einen relativen Pfad handeln.
Für alle anderen Funktionen, einschließlich aller Funktionen, die in einer interaktiven Eingabeaufforderung definiert wurden, oder einer Autoload-Funktion, deren Pfad noch nicht aufgelöst wurde, ist dies die leere Zeichenfolge. Das Hash-Element wird jedoch nur so lange als definiert gemeldet, wie die Funktion vorhanden ist: Die Schlüssel für diesen Hash sind dieselben wie die für
$functions
.
Sie können also Folgendes tun:
echo $functions_source[cp]
Antwort4
Terdons Antworthat Ihnen bereits den entsprechenden grep
Befehl gegeben, um alle möglichen Varianten einer Funktionsdefinition abzufangen.
Ich möchte noch zwei Punkte hinzufügen.
Um eine Liste der Dateien zu erhalten, dieGenau genommeneinlesen (z. B. könnte eine nicht standardmäßige Datei aus einer anderen Datei stammen!), können Sie
zsh
mitSOURCE_TRACE
aktivierter Option aufrufen:$ zsh -o sourcetrace +/etc/zshenv:1> <sourcetrace> +/home/user/.zshrc:1> <sourcetrace> +/home/user/.zcompdump:1> <sourcetrace> +/home/user/.zshrc-last:1> <sourcetrace>
Mit diesem ,,grep-Ansatz'' werden Sie keine Funktionen abfangen, dieautomatisch geladenüber das
autoload
eingebaute. Überprüfen Sie alsofpath
auch Ihr :$ for i ($fpath) { ls -l "$i"/cp }