У меня есть эта раздражающая проблема в моей оболочке 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
команду для перехвата всех возможных вариантов определения функции.
Хочу добавить еще два момента.
Чтобы получить список файлов, которыена самом делечтение (например, нестандартный файл может быть источником другого файла!), можно вызвать
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>
С помощью этого ,,grep-подхода'' вы не поймаете функции, которыеавтозагруженныйчерез
autoload
встроенный. Так что проверьтеfpath
и свой :$ for i ($fpath) { ls -l "$i"/cp }