web-dev-qa-db-ja.com

zshで関数のソースを見つける

関数がどこかで宣言されていて、その関数の名前が「cp」であるため、通常のcpの動作をオーバーライドしているzshシェルにこの厄介な問題があります。関数宣言を見つけようとしていますが、見つかりません。私はすでに.zshrcの通常の場所と、.zshrcに含まれている他のさまざまなソースを調べましたが、今のところ何もありません。

私が試した他のこと:

  • grep -r 'function cp' .(〜から)
  • whence -f cp(関数定義を提供しますが、宣言元は提供しません)

何か案は?

9
asolberg

まず第一に、関数はfunctionキーワードなしで定義できるので、より良い検索は

grep 'cp()' .*

これにより、.zshrc.profileなどのファイルが検索されます。それでも何も見つからない場合は、zshによってロードされたさまざまなファイルを確認することもできます。これらは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)

デフォルトでは、$ZDOTDIR$HOMEにする必要があります。したがって、このコマンドは問題のあるファイルを見つける必要があります。

grep 'cp()\|cp ()' ~/.zshenv ~/.zprofile ~/.zshrc ~/.zlogin /etc/zsh/zshenv \
 /etc/zsh/zprofile /etc/zsh/zshrc /etc/zsh/zlogin 

関数名と関数自体の間にスペースを入れることもできるので、\|を追加しました。最後に、 @ Dennisが指摘functionキーワードを使用する場合は、括弧も省略できます。したがって、さらに安全にするために、これを実行します。

grep -E 'function cp|cp *\(\)' ~/.zshenv ~/.zprofile ~/.zshrc ~/.zlogin \
  /etc/zsh/zshenv /etc/zsh/zprofile /etc/zsh/zshrc /etc/zsh/zlogin 
4
terdon

私は今日これをする必要があり、それを見つけましたwhence -v関数定義を含むファイルを出力します。

$ whence -v function_name
function_name is a Shell function from /path/to/file
18
Will Adams

新しいバージョンのzsh(5.4以降、コミットで追加 34f70c5 )は、$functions_sourceモジュールの一部としてzsh/parameter配列をサポートします(ドキュメント:man zshmodules )::

functions_source

この読み取り専用の連想配列は、有効な関数の名前を、関数のソースを含むファイルの名前にマップします。

すでにロードされているか、絶対パスで自動ロードのマークが付けられている、またはパスが「functions -r」で解決されている自動ロードされた関数の場合、これは自動ロードで見つかったファイルであり、絶対パスに解決されます。

スクリプトまたはソースファイルの本体内で定義された関数の場合、これはそのファイルの名前です。この場合、これはそのファイルに最初に使用された正確なパスであり、相対パスである可能性があります。

対話型プロンプトで定義された関数や、パスがまだ解決されていない自動ロード関数を含むその他の関数の場合、これは空の文字列です。ただし、ハッシュ要素は、関数が存在する限り、定義されたとおりに報告されます。このハッシュのキーは、$funcionsのキーと同じです。

だから、あなたはすることができます

echo $functions_source[cp]
3
univerio

Terdonの答え 関数定義のすべての可能なバリアントをキャッチするための適切なgrepコマンドがすでに提供されています。

もう2点付け加えたいと思います。

  1. 実際に読み込まれているファイルのリストを取得するには(たとえば、非標準ファイルは別のファイルから供給されている可能性があります!)、zshを呼び出すことができます。とともに SOURCE_TRACEオプションが有効:

    $ zsh -o sourcetrace
    +/etc/zshenv:1> <sourcetrace>
    +/home/user/.zshrc:1> <sourcetrace>
    +/home/user/.zcompdump:1> <sourcetrace>
    +/home/user/.zshrc-last:1> <sourcetrace>
    
  2. この, grep-approach ''を使用すると、autoloadビルトインを介してautoloadedされている関数をキャッチできません。したがって、fpathもチェックしてください。

    $ for i ($fpath) { ls -l "$i"/cp }
    
0
mpy