是否有可能知道launchctl
命令加载的.plist文件位置?
launchctl list
会列出标签名称,launchctl list LABEL
会显示其内容,但我找不到.plist文件的位置。
我知道它将位于/Library/LaunchAgent
或~/Library/LaunchAgent
或其他地方,但我不想在所有通过launchctl
命令列出的作业路径中搜索。
是否有可能知道launchctl
命令加载的.plist文件位置?
launchctl list
会列出标签名称,launchctl list LABEL
会显示其内容,但我找不到.plist文件的位置。
我知道它将位于/Library/LaunchAgent
或~/Library/LaunchAgent
或其他地方,但我不想在所有通过launchctl
命令列出的作业路径中搜索。
从macOS 10.12.6开始(之前版本不确定),可以使用launchctl dumpstate
命令,获取有关所有正在运行进程的丰富信息。
在与该作业相关的信息的第一行中查找<LABEL> = {
以下是获取所有活动守护程序及其属性列表路径的单行命令:
grep -B 1 -A 4 "active count = 1$" <<< "$(launchctl dumpstate)"
更新:自10.12版本以来,macOS已添加了其他值,因此grep -A n
已增加到4行。
launchctl dumpstate
非常有用;请注意,它是launchctl
的一个未记录的子命令,甚至没有列在“LEGACY SUBCOMMANDS”下。 - smci这个问题经常出现,不幸的是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 或更高版本的用户,我建议使用 Joel Bruner 的解决方案。
launchctl list
中使用的进程名称在plist中声明。虽然plist应该位于上述位置,但它们几乎可以放在任何地方。locate *.plist | grep org.postgresql.postgres
将其缩小到4个文件。在最近的macOS版本中,您可以使用launchctl print
命令。您必须知道它正在运行的域,例如system
或gui/<uid>
。您可以在man页面中找到一些其他域,但到目前为止,我只看到了在这两个域下运行的服务。示例:
% 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或其后版本中实现的。
这个问题可能没有答案!似乎不是 launchctl list
中的所有内容都有 plist 文件。
如上所述,launchctl dumpstate
将为您提供有关事物的大量信息,包括 plist 路径(如果存在)。
您可以运行此命令以大致查看正在运行的所有内容及其 plist 路径的列表。
launchctl dumpstate | grep -A4 " = {" | grep -B 3 -A 3 -E "active count = [1-9]"
(虽然这似乎也包括由launchd管理的守护程序以外运行的其他程序?)
代理/守护进程下面会有一个路径字段。通常,这些路径指向由Reed的答案描述的标准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
幸运的是,这种做法并不太流行,因此通常在标准位置搜索就足够了。
但这并不是最棘手的问题。我不知道具体情况,但似乎可以在没有相应plist文件的情况下加载launchctl
服务。例如,这是dumpstate为1Password助手守护程序所说的内容。
➜ 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
launchctl list
中看到一个辅助程序,可能在文件系统中没有任何plist。因此,我不知道如何使用launchctl unload
来卸载此服务,因为卸载需要plist路径!由于这个进程是由launchd
管理的,即使我使用pkill -9 onepassword7-helper
,launchd
也会发现该进程停止并立即重新启动它。^
和⌥
,将出现一个特殊的“完全退出1Password”选项)grep
几年了,直到我刚刚读到这篇文章时才意识到 -B
和 -A
标志。这非常有用。谢谢! - Geoff由于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
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;
}