man launchctl
' remarks that:
LEGACY SUBCOMMANDS
Subcommands from the previous implementation of launchd are generally available,
though some may be unimplemented. Unimplemented subcommands are documented
as such.
⋮
bslist [PID | ..] [-j]
This subcommand is not implemented and has been superseded by the print
subcommand, which provides much richer information.
at least as of OS X v10.11.x 'El Capitan.' (Presumably, this was also the case in v10.10.x 'Yosemite,' as that was the OS release that first included 'launchd
2.0,' if I'm reading/recalling my history correctly.) What arguments, then, would one pass to 'launchctl print
' to get output like what the 'bslist
' sub-command used to provide? Would you need to filter it any (using grep
, sed
, awk
, etc.) to get the desired result(s)?
('launchctl print system
' spews a bunch of data out, but I'm not clear on whether that includes the same information the 'bslist
' sub-command would have output in the past or, if so, where in the former's output said information might be. Its 'endpoints
' key contains a list similar to the example provided in Listing 1 in the 'Mach Bootstrap Basics' section of this old, outdated Apple documentation on 'Daemons and Agents,' but I'm uncertain if that's what I'm looking for, particularly since it contains a couple extra columns.)
Best Answer
Short answer
Use:
If you prefer a script, create a file, for example
/usr/local/bin/bslist
, with these contents:and make it executable:
chmod a+x /usr/local/bin/bslist
. (See the end of this post for an explanation of how the script works.)Note that both the command and script above fully support
sudo
:To the get the output equivalent to running
sudo launchctl bslist
, simply prependsudo
:sudo bash -c "if [ \$(id -u) -eq 0 ]; then domain=system; else domain=\"user/\$(id -u)\"; fi; launchctl print \$domain | sed -e '1,/endpoints = {/d' -e '/}/,\$d' -e 's/.* \([A|D]\)\( *\)\(.*\)/\1 \3/'"
sudo /user/local/bin/bslist
.To get the output for a different user
<user>
, that is, the outputsudo -u <user> launchctl bslist
would produce, prependsudo -u <user>
instead.(Tested in macOS 10.15 "Catalina" and OS X 10.10 "Yosemite".)
Long answer
The long gone
bslist
bslist
was removed with OS X 10.10 "Yosemite". According to OS X 10.9 Mavericks' man page of launchctl,bslist
Typical output is:
where:
A
for "Active" andD
"On-demand")print
, the new kid in townApple replaced
bslist
with an enhanced subcommand:print
.Why enhanced? As nicely explained here, bootstrap services are arraged in a hierarchical namespace. While
bslist
hides this complexity from the user by making the following assumptions:sudo
),bslist
outputs the system-wide domain.print
takes another approach: it gives the user a finer control on the output by accepting the desired domain as an argument (see the man page of launchctl for details).Making
print
behave likebslist
Luckily, after running
bslist
in OS X 10.9 "Mavericks" andprint
in OS X 10.10 "Yosemite" multiple times and comparing the output, I can confirm that all information provided bybslist
is contained inprint
:bslist
when run as root can is provided by thesystem
option in the endpoints array.print
with theuser/<UID>
option, also in the endpoints array.The exact commands are provided above in the short answer section of this post, here I revisit the script (with comments) for a better understanding of what it does:
A few words on bootstrap services
This answer deals with bootstrap services, but, what are they?
macOS uses a hybrid kernel, called XNU, that combines the Mach kernel developed at Carnegie Mellon University with components from FreeBSD and a C++ API for writing drivers called IOKit.
Interprocess communication (IPC) plays a large role in the Mach component of the kernel. The Mach implementation of IPC relies on the notion of "ports".
In Mach IPC, ports are somewhat similar to TCP and UDP ports: in the same way that a process requires the TCP/UDP port of a resource on the network to be able to communicate with it, processes communicating over Mach IPC need to know the port of the desired service. This information is provided by the bootstrap server, which is one of the functions of the
launchd
process.So, in this oversimplified analogy, the bootstrap server plays a role roughly equivalent to
/etc/services
.As with the
/etc/services
file, the bootstrap server maintains a list of ports and names. You can get a list of them withlaunchctl print
, just look for the endpoint array section, for example:Stretching the analogy, the difference between the services file and Mach IPC is that, while
/etc/services
is static, the list of ports and names the bootstrap server maintains is dynamic, as services can request to be added to it.And that brings us back to the original question: Bootstrap services are simply services registered with the bootstrap server.
References
If you are interested in the macOS launch process, Mach IPC,
launchd
and its internals, you may find these references useful:See Mach Bootstrap Basics and Mach Messaging and Mach Interprocess Communication (IPC) for more information on bootstrap basics and IPC.
See Kernel Architecture Overview for more information on the architecture of the macOS kernel.
See Mach Overview for an overview of the Mach component of the macOS kernel.
See Mac OS X For Unix Geeks and The Alpha and the Omega - launchd for an overview of the startup process in macOS.
See LAUNCHCTL 2.0 SYNTAX for a discussion about changes in the
launchctl
syntax.See Mach Message and Bootstrap Server on OS X for an overview of Mach messaging and the bootstrap server.
See the source code of the bslist subcommand (look for
bslist_cmd
) for an insight onlaunchctl
. You can downloadlaunchd
tarballs from here.See macOS IPC Man in the Middle for a presentation on implementation flaws in Mach IPC.