2016-04-11 22 views
2

私はここで非常に基本的なセットアップパターンを使用しようとしています:私は、特定のツール(ocamlcの2つの異なるインストールがありますが、それは本当に問題ではありません)。 1つのツールを選択するために、エントリを前置することによってPATH変数をオーバーライドしようとします。 zshがPATHエントリの順序を無視するのはなぜですか?

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

(一つは、ライブラリディレクトリがそのインストールにハードコードされているので、それは2番目のエントリを使用していることがわかります)

はバッシュの動作:

% 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 

しかし、zshのは、古いエントリを使用しています

% 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 

なぜ、zshは最初のPATHエントリを無視しますか? tはそれをwhereの最初の要素として列挙しますか?

編集:

% 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:

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

コンフィグがある:ここでは はSETOPT出力で同じバイナリを起動していないことのzshを検証するために は、ここに別の実行でありますgrml configにはhereと.localファイルにいくつかのパス変数があります。

答えて

0

zshはPATHエントリをスキップしません。ただし、エイリアス機能とシェル機能の優先順位はあります。これはあなたのケースには当てはまりません。あなたがそれらのものを持っていたら、whereもこれをリストしています。あなたのケースでは

、もしwhereocamlcコマンドは、同じシェルで実行されており、そのためには、あなたはocamlc/home/choeger/ueb/uebb/amsun-integration/Runtime/test_src/../../opam/4.02.3/bin/ocamlcを実行することをかなり確信することができます。この絶対パスでOcamを明示的に実行しようとしましたか?私はあなたが同じ出力を得るだろうと確信しています。

BTW、type -aは、一般に、whereよりも少し詳細な情報を提供します。

+1

残念ながら、それはありません。編集を参照してください。 – choeger

+0

別の理由が必要です。理論的には、 'ocamlc'は、プログラムがこれを行うことは稀ですが、どのように呼び出されたかを(PATHまたはabsパスによって)問い合わせることができます。明示的にPATH、すなわち 'PATH =/home/choeger/ueb/uebb/amsun-integration/tests/pendulum /../../ opam/4.02.3/bin ocamlc -v'を省略しようとすると....この場合、zshには他のPATHがありません。本当に確かめたいのであれば、 'ocamlc'の代わりに' command ocamlc'を書いてください。キーワード 'command'はエイリアス拡張とシェル関数定義をバイパスします。 – user1934428

+1

コマンドは何も変更しません。パスを明示的に制限すると、予期した結果が得られます。 – choeger

3

デフォルトでは、zshはコマンドが実行されたときに最初にハッシュされます。 2回目に実行すると、ハッシュされたパスが使用されます。ハッシュテーブルは、実行リフレッシュするには

rehash 

または

hash -r 

これは自動的にあなたがPATH変更して新しい実行ファイルはPATHですでにディレクトリに追加されたときに、その主な用途は、あるたびに起こるはず。


:以下は、特定のユースケースのためにやり過ぎかもしれません。しかし、それはまた、問題を解決し、少し異なるユースケースのために興味があるかもしれません。それはないだろう、まだハッシュテーブルを使用することになります

setopt nohashcmds 

zshながら:あなたは(おそらく無視できる)パフォーマンスヒットを気にしない場合は

、あなたはHASH_CMDSオプションを無効にすることで、コマンドのハッシュを無効にすることができますすべてのコマンドを自動的に追加します。したがって、コマンドが他の手段によってハッシュテーブルに入力されない限り、zshは毎回コマンドのためにPATHをチェックします。

これは、オプションCORRECTが設定されている場合でも問題を引き起こす可能性があります。これは、スペル訂正を提供するためにハッシュテーブルを設定するので、PATHが変更されたときに必ず更新する必要はありません。テーブルを自動的にリフレッシュするには、プロンプトが表示される前に毎回実行されるprecmdフックを使用します。

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

それはいい答えです。そして、実際には、「ハッシュ」は、エントリがまだ古い場所を指していることを示しています。残念ながら、再ハッシュ処理はここでは変わりません。 rehashはどこから入手できますか?私はここに本物のバグを打ったのですか? – choeger

+0

'PATH'から情報を取得するはずです。奇妙な...あなたは 'zsh'のどのバージョンを使っていますか? – Adaephon

+0

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

関連する問題