如何知道特定的launchd.plist文件位置?

时间:2013-08-29 05:09:09

标签: macos launchd

是否可以知道加载到launchctl命令的.plist文件位置?

标签名称列在“launchctl list”中,其内容可以通过“launchctl list LABEL”查看,但我找不到.plist文件位置。

我知道它会位于/ Library / LaunchAgent或〜/ Library / LaunchAgent之类的东西, 但我不希望在使用launchctl命令列出所有作业时搜索路径。

8 个答案:

答案 0 :(得分:14)

这个问题出现了很多,不幸的是locatemdfind都没有显示我系统上相应目录的结果。我在我的.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查找文件的目录。它可能找不到所有内容,因为作业可以由用户和/或其他进程手动加载。

答案 1 :(得分:4)

launchctl list中使用的进程名称在plist中声明。虽然plist应该在上面提到的位置,但它们几乎可以在任何地方。

我找到了我正在寻找的'找到的那个。我在找org.postgresql.postgres     locate *.plist | grep org.postgresql.postgres 将其缩小到4个文件

答案 2 :(得分:3)

从macOS 10.12.6开始(不确定早期版本)可以调用:launchctl dumpstate,您将获得有关所有正在运行的进程的大量信息

查找<LABEL> = {作为与该职位有关的第一行信息

这是一个用于获取所有活动守护进程及其plist路径的衬垫:

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

答案 3 :(得分:2)

这是列出所有已加载的.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

或其他版本:

  

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

说明:

  • find位于以下位置的所有.plist个文件:/System/Library/Launch* /Library/Launch* ~/Library/Launch*
  • 使用PlistBuddy命令打印所有找到的Label个文件的.plist
  • 使用-print的{​​{1}}参数打印该文件的路径。
  • 获取加载到find的所有作业的另一个列表,并将其用作launchd的模式文件。
  • 过滤两个列表并查找常用元素并打印其标签及其路径(grep -f)。

答案 4 :(得分:1)

在最新版本的 macOS 中,您可以使用 launchctl print 命令。您必须知道它在哪个域下运行,例如systemgui/<uid>。您可以在手册页中找到一些其他域,但到目前为止,我只看到在这两个域下运行的服务。示例:

% launchctl print gui/$(id -u)/com.apple.cloudphotod  | grep path
    path = /System/Library/LaunchAgents/com.apple.cloudphotod.plist

 % launchctl print system/com.openssh.sshd | grep path 
    path = /System/Library/LaunchDaemons/ssh.plist
    stderr path = /dev/null

我相信这个命令是在 High Sierra 或附近实施的。

答案 5 :(得分:0)

由于launchctl list列出PID,一种方法是使用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

答案 6 :(得分:0)

这个问题可能没有答案!似乎并非launchctl list中的所有内容都具有plist文件。

如前所述,launchctl dumpstate将为您提供大量信息,包括plist路径(如果存在)。

您可以运行此命令以大致查看正在运行的所有内容及其plist路径的列表。

launchctl dumpstate | grep -A4 " = {" | grep -B 3 -A 3 -E "active count = [1-9]"

(尽管这似乎还包括其他运行的程序,这些程序不是由launched管理的守护进程?)

代理/守护程序将在其标识符下方具有路径字段。通常,路径指向Reed's answer描述的标准5个位置中的plist文件。但是,不一定如此。例如,Steam从非标准位置加载launchctl服务。

➜ launchctl dumpstate | grep -A4 " = {" | grep -B 3 -A 3 -E "active count = [1-9]"  | grep valve
com.valvesoftware.steam.ipctool = {
    path = /Users/chris/Library/Application Support/Steam/com.valvesoftware.steam.ipctool.plist

幸运的是,这种做法不太流行,因此通常只需搜索标准位置即可。

但这不是最棘手的事情。我不知道具体细节,但看来launchctl服务可以完全加载而无需相应的plist文件。例如,这就是dumpstate对1Password helper守护程序的说明。

➜ launchctl dumpstate | grep -A4 " = {" | grep -B 3 -A 3 -E "active count = [1-9]"  | grep -A4 "onepassword7-helper = {"
2BUA8C4S2C.com.agilebits.onepassword7-helper = {
    active count = 5
    path = (submitted by smd.1154)
    state = running

我不知道“ smd提交”的真正含义是什么,但是归结为即使我在launchctl list中看到了一个助手,文件系统上也可能没有任何plist。因此,我不知道如何launchctl unload这项服务,因为卸载需要plist路径!而且由于此过程是由launchd管理的,所以即使我pkill -9 onepassword7-helperlaunchd也会看到该过程已停止并重新开始。

(对于这个特定的1Password示例,很幸运,如果您在单击Quit 1Password时按住^,则会出现一个特殊的“完全Quite 1Password”选项)

答案 7 :(得分:0)

在 Catalina 上,我设计了这个脚本来打印出在 system 域或登录用户中找到的所有正则表达式匹配对象的 plist。请注意,这是一个 BASH 脚本,但也适用于我的 ZSH 测试。

用法:find_loaded_plist [ regex ]

请在下面的评论中报告错误/建议。

find_loaded_plist() {
     launchctl list  | 
     awk "NR>1 && /${1:-^}/  { print \$3 }"  | 
     while read name; do
             launchctl print system/$name 2>/dev/null | 
                sed -n 's/^[[:space:]]*path = //p'
             for u in $(users |xargs id -u ) ; do                                 
                  launchctl print uid/$u/$name 2>/dev/null |
                     sed -n 's/^[[:space:]]*path = //p'
             done;
     done; 
}