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

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

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

私が試した他のこと:

  • grep -r 'function cp' .(〜より)
  • whence -f cp(関数の定義は示しますが、どこで宣言されているかは示しません)

何か案は?

答え1

まず、関数は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 

答え2

今日これを実行する必要があり、whence -v関数定義を含むファイルが出力されることがわかりました。

$ whence -v function_name
function_name is a shell function from /path/to/file

答え3

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

functions_source

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

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

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

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

だから、あなたはできる

echo $functions_source[cp]

答え4

テルドンの答え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アプローチ」では、自動ロード組み込み関数を介してautoload。したがって、 もチェックしてくださいfpath

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

関連情報