Как узнать конкретное местоположение файла launchd.plist?

Возможно ли узнать местоположение файла .plist, которое загружается в команду launchctl?

Название метки отображается в списке "launchctl list", и его содержимое можно просмотреть с помощью "launchctl list LABEL", но я не могу найти расположение файла .plist.

Я знаю, что он будет расположен в /Library/LaunchAgent или ~/Library/LaunchAgent или что-то еще, но я не хочу искать вокруг путей, пока все задания перечислены с помощью команды launchctl.

Ответ 1

Эта проблема часто возникает, и, к сожалению, locate и mdfind не показывают результаты из соответствующих каталогов в моей системе. Я добавил следующую функцию в .bashrc, чтобы быстро найти каталоги, где launchctl ищет plist файлы.

launchctlFind () {
    LaunchctlPATHS=( \
        ~/Library/LaunchAgents \
        /Library/LaunchAgents \
        /Library/LaunchDaemons \
        /System/Library/LaunchAgents \
        /System/Library/LaunchDaemons \
    )

    for curPATH in "${LaunchctlPATHS[@]}"
    do
        grep -r "$curPATH" -e "$1"
    done
    return 0;
}

Обратите внимание, что это проверяет только те каталоги, где launchctl ищет файлы при загрузке и входе в систему. Он может не найти все, потому что задания могут быть загружены вручную пользователем и/или другими процессами.

ОБНОВЛЕНИЕ: Для тех, кто работает с MacOS 10.12.6 или выше, я бы рекомендовал использовать решение Джоэля Брунера ниже.

Ответ 2

Как и в macOS 10.12.6 (не уверен в более ранних версиях), можно вызвать: launchctl dumpstate и вы получите массу информации обо всех запущенных процессах

Найдите <LABEL> = { как первую строку информации, относящейся к этому заданию

Здесь один лайнер, чтобы получить все активные демоны и их пути plist:

grep -B 1 -A 1 "active count = 1$" <<< "$(launchctl dumpstate)"

Ответ 3

Имя процесса, используемое в launchctl list, объявляется в plist. Хотя plist должен находиться в указанном выше месте, они могут быть практически в любом месте.

Я нашел plist, который я искал, чтобы найти его. Я искал org.postgresql.postgres   locate *.plist | grep org.postgresql.postgres сузил его до 4 файлов

Ответ 4

Вот команда для вывода списка всех загруженных файлов .plist и соответствующих им файлов:

find /System/Library/Launch* /Library/Launch* ~/Library/Launch* -name '*.plist' -exec sh -c '/usr/libexec/PlistBuddy -c "Print Label" {} && echo {}' ';' | grep -wf <(launchctl list | grep -o "\S\+\..*$") -A1 | strings

или другая версия:

find /System/Library/Launch* /Library/Launch* ~/Library/Launch* -name '*.plist' -exec /usr/libexec/PlistBuddy -c "Print Label" {} ';' -print | grep -wf <(launchctl list | grep -o "\S\+\..*$") -A1 | strings

Объяснение:

  • find все файлы .plist в следующих местах: /System/Library/Launch* /Library/Launch* ~/Library/Launch*
  • Используйте команду PlistBuddy для печати Label всех найденных файлов .plist.
  • Используйте параметр -print в find, чтобы напечатать путь к этому файлу.
  • Получить другой список всех заданий, загруженных в launchd, и использовать в качестве файла шаблона для grep -f.
  • Отфильтруйте оба списка, найдите общие элементы и напечатайте их метку вместе с путем (-A1).
  • Фильтруйте через strings, чтобы избежать печати двоичных файлов.

Ответ 5

Поскольку launchctl list list PIDs, один из методов заключается в использовании команды lsof для просмотра всех загруженных файлов процесса, например.

launchctl list | grep -o '^[0-9]\+' | xargs -n1 lsof -p | grep plist$

Другой способ - запустить команду fs_usage и перезагрузить файл .plist, например

sudo fs_usage | grep -w launchd | grep -w plist