2016-04-11 2 views
2

Ich versuche hier ein sehr einfaches Setup-Muster zu verwenden: Ich habe zwei verschiedene Installationen eines bestimmten Tools (ocamlc, aber das ist nicht wirklich wichtig). Um ein Werkzeug auszuwählen, versuche ich, die PATH-Variable durch Voranstellen eines Eintrags zu überschreiben.Warum ignoriert zsh die Reihenfolge der PATH-Einträge?

% where ocamlc  
/home/choeger/ueb/uebb/amsun-integration/Runtime/test_src/../../opam/4.02.3/bin/ocamlc 
/home/choeger/.opam/4.02.3/bin/ocamlc 
/usr/bin/ocamlc 

jedoch die zsh verwendet immer noch den älteren Eintrag:

% ocamlc -v   
The OCaml compiler, version 4.02.3 
Standard library directory: /home/choeger/.opam/4.02.3/lib/ocaml 

(Man kann sehen, dass es den zweiten Eintrag verwendet, weil das Bibliotheksverzeichnis zu dieser Installation fest einprogrammiert wird)

Bash verhält wie erwartet:

% bash -c "ocamlc -v" 
The OCaml compiler, version 4.02.3 
Standard library directory: /home/choeger/ueb/uebb/amsun-integration/opam/4.02.3/lib/ocaml 

Also warum ignoriert zsh den ersten PATH-Eintrag, obwohl ich t listet es als erstes Element von where auf?

edit: Um diese zsh zu überprüfen nicht die gleiche binäre aufrufen, hier ist ein weiterer Lauf:

% type -a ocamlc 
ocamlc is /home/choeger/ueb/uebb/amsun-integration/tests/pendulum/../../opam/4.02.3/bin/ocamlc 
ocamlc is /home/choeger/.opam/4.02.3/bin/ocamlc 
ocamlc is /usr/bin/ocamlc 
% ocamlc -v 
The OCaml compiler, version 4.02.3 
Standard library directory: /home/choeger/.opam/4.02.3/lib/ocaml 
% /home/choeger/ueb/uebb/amsun-integration/tests/pendulum/../../opam/4.02.3/bin/ocamlc -v 
The OCaml compiler, version 4.02.3 
Standard library directory: /home/choeger/ueb/uebb/amsun-integration/opam/4.02.3/lib/ocaml 

edit2: Hier ist die setopt Ausgang:

% setopt 
autocd 
autopushd 
nobeep 
completeinword 
correct 
extendedglob 
extendedhistory 
histignorealldups 
histignorespace 
nohup 
interactive 
interactivecomments 
longlistjobs 
monitor 
nonomatch 
pushdignoredups 
shinstdin 
zle 
% 

Config ist Die grml-Konfiguration hat here plus einige Pfadvariablen in der .local-Datei gefunden.

Antwort

0

zsh überspringt PATH-Einträge nicht. Es gibt jedoch Priorität von Alias- und Shell-Funktionen. Dies gilt nicht für Ihren Fall, denn wenn Sie einen von denen hätten, hätte where dies auch aufgeführt.

In Ihrem Fall, wenn die where und der ocamlc Befehl haben in der gleichen Shell, und in dieser Reihenfolge ausgeführt worden ist, können Sie ziemlich sicher sein, dass ocamlc/home/choeger/ueb/uebb/amsun-integration/Runtime/test_src/../../opam/4.02.3/bin/ocamlc ausführt. Haben Sie Ocam explizit über diesen absoluten Pfad ausgeführt? Ich wette, dass Sie die gleiche Ausgabe erhalten werden.

BTW, type -a würde im Allgemeinen ein bisschen detailliertere Informationen als where geben.

+1

Leider nicht. Siehe Bearbeiten. – choeger

+0

Es muss einen anderen Grund haben. Theoretisch könnte "ocamlc" abfragen, wie es aufgerufen wurde (über PATH oder durch den ABS-Pfad), obwohl es selten ist, dass Programme dies tun. Versuchen Sie, den PATH explizit zu reduzieren, dh 'PATH =/home/choeger/ueb/uebb/amsun-integration/tests/pendel /../../ opam/4.02.3/bin ocamlc -v' .... In diesem Fall hat zsh keinen anderen PATH zur Auswahl. Wenn Sie wirklich sicher sein wollen, schreiben Sie 'command ocamlc' anstelle von' ocamlc'. Das Schlüsselwort 'command' würde Alias-Expansions- und Shell-Funktionsdefinitionen umgehen. – user1934428

+1

Befehl ändert nichts, explizite Einschränkung des Pfades führt zum erwarteten Ergebnis. – choeger

3

Standardmäßig werden die Positionen der Befehle beim ersten Ausführen von zsh in Hashwerte umgewandelt. Bei der zweiten Ausführung wird der Hash-Pfad verwendet. So aktualisieren Sie die Hash-Tabelle

rehash 

oder

hash -r 

Das sollte geschehen, automatisch jedes Mal, wenn Sie PATH und seine Hauptanwendung ändern ausgeführt wird, wenn neue ausführbare Dateien zu Verzeichnissen hinzugefügt werden bereits in PATH.


Hinweis: Folgendes könnte viel des Guten für den spezifischen Anwendungsfall sein. Es löst aber auch das Problem und könnte für etwas andere Anwendungsfälle von Interesse sein.

Wenn Sie nicht über die (wahrscheinlich vernachlässigbar) Leistungseinbußen ist es egal, können Sie Hashing von Befehlen deaktivieren, indem Sie die HASH_CMDS Option zu deaktivieren:

setopt nohashcmds 

Während zsh noch die Hash-Tabelle verwenden, wird es nicht fügt automatisch jeden Befehl hinzu. Wenn also auf andere Weise kein Befehl in die Hash-Tabelle eingegeben wird, überprüft zsh den Befehl jedes Mal auf PATH.

Dies kann immer noch zu Problemen führen, wenn die Option CORRECT gesetzt ist. Da dies die Hash-Tabelle festlegt, um eine Rechtschreibkorrektur bereitzustellen, wird sie jedoch nicht notwendigerweise aktualisiert, wenn sich PATH ändert. Um die Tabelle automatisch zu aktualisieren, können Sie den Haken precmd verwenden, der jedes Mal ausgeführt wird, bevor die Eingabeaufforderung gedruckt wird.

autoload -Uz add-zsh-hook 
auto_rehash() { 
    rehash 
} 
add-zsh-hook precmd auto_rehash 
+0

Das ist eine nette Antwort. Und tatsächlich zeigt "hash", dass der Eintrag immer noch auf den alten Standort zeigt. Leider ändert die Umrüstung nichts an dieser Stelle. Woher kommt rehash? Habe ich hier einen echten Fehler gefunden? – choeger

+0

Es sollte seine Informationen von 'PATH' erhalten. Seltsam ... Welche Version von 'zsh' benutzt du? – Adaephon

+0

zsh 5.1.1 (x86_64-redhat-linux-gnu) – choeger

Verwandte Themen