Поиск источника функции в 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команду для перехвата всех возможных вариантов определения функции.

Хочу добавить еще два момента.

  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 }
    

Связанный контент