pylaunchd
pylaunchd copied to clipboard
added an option to filter out system services
@tcptps: apparently you are assuming a certain macos version which works for your scenario; Apple states explicitly that the format generate by their tools like like launchctl is not meant to be parsed and can change without notification between different versions of the OS.
On macos Ventura 13.0.1 your branch triggers an arrayIndex error because of string splitting on a separator that does not exist.
For example, the output of launchctl print user/501/com.apple.iCloudHelper will fail with your change:
user/501/com.apple.iCloudHelper = {
active count = 0
path = /System/Library/PrivateFrameworks/AOSKit.framework/Versions/A/XPCServices/com.apple.iCloudHelper.xpc
type = XPCService
state = not running
bundle id = com.apple.iCloudHelper
bundle version = 282
program = /System/Library/PrivateFrameworks/AOSKit.framework/Versions/A/XPCServices/com.apple.iCloudHelper.xpc/Contents/MacOS/com.apple.iCloudHelper
default environment = {
PATH => /usr/bin:/bin:/usr/sbin:/sbin
}
environment = {
MallocSpaceEfficient => 1
XPC_SERVICE_NAME => com.apple.iCloudHelper
}
domain = user/501
asid = 100027
minimum runtime = 10
base minimum runtime = 10
exit timeout = 5
runs = 882
last exit code = 0
endpoints = {
"com.apple.iCloudHelper" = {
port = 0x2ed07
active = 0
managed = 1
reset = 0
hide = 0
watching = 1
}
}
spawn type = adaptive (6)
jetsam priority = 40
jetsam memory limit (active, soft) = 15 MB
jetsam memory limit (inactive, soft) = 15 MB
jetsamproperties category = xpcservice
jetsam thread limit = 32
cpumon = default
job state = exited
probabilistic guard malloc policy = {
activation rate = 1/1000
sample rate = 1/0
}
properties = xpc bundle | supports transactions | supports pressured exit | joins gui session | parameterized sandbox | exponential throttling
}
In any case, it's not clear what you want to achieve. There is a already a dropdown where you can select the launchd domain which includes User System and GUI.
@glowinthedark thx for the hint. I know that you arent supposed to parse the output but since it is pseudo parsed multiple times in the project anyways I didnt see any harm to add another function in the same spirit as the other ones. I have adjusted the code and it should now also work on Ventura. (The change is not automatically applied to the PR afaik because you closed it) This is what the output looks like on my machine:
properties = {
partial import = 0
launchd bundle = 0
xpc bundle = 1
keepalive = 0
runatload = 0
dirty at shutdown = 0
low priority i/o = 0
low priority background i/o = 0
legacy timer behavior = 0
exception handler = 0
multiple instances = 0
supports transactions = 1
supports pressured exit = 1
enter kdp before kill = 0
wait for debugger = 0
app = 0
system app = 0
creates session = 0
inetd-compatible = 0
inetd listener = 0
abandon process group = 0
one-shot = 0
requires reap = 0
event monitor = 0
penalty box = 0
pended non-demand spawn = 0
role account = 0
launch only once = 0
system support = 0
app-like = 0
inferred program = 0
joins gui session = 1
joins host session = 0
parameterized sandbox = 0
resolve program = 0
abandon coalition = 0
extension = 0
nano allocator = 0
no initgroups = 0
start on fs mount = 0
endpoints initialized = 1
disallow all lookups = 0
system service = 0
}
I want to remove all jobs from the list that have system service = 1 because they are provided by apple and protected by SIP and therefore cant be changed anyways and they are irrelevant in most usecases where you want to check what services are installed on your machine.
It is very obvious that at some point apple provided a change to the output so properties = only contains a list of properties which are true(= 1).
With your last push there is still a list index out of range exception at lin3 373:
https://github.com/tcptps/pylaunchd/blob/main/pylaunchd_gui.py#L373 <— you are splitting twice without checking the number of chunks. Apparently not all plists follow the same structure.
Did you look through man launchctl? It would be way better if filtering could be done by passing extra flags to launchctl.
It might also be possible to filter the services indirectly via their path; according to the man page:
FILES
~/Library/LaunchAgents Per-user agents provided by the user.
/Library/LaunchAgents Per-user agents provided by the administrator.
/Library/LaunchDaemons System wide daemons provided by the administrator.
/System/Library/LaunchAgents OS X Per-user agents.
/System/Library/LaunchDaemons OS X System wide daemons.
@glowinthedark I am sorry my bad, I simply missed the ~~closing~~ opening bracket I fixed it now and verfied it with your example this time, as I was previously flying blind.
yes filtering by Path might be an option, but this should work for now. I looked through the manpage again just to be shure but couldnt find anything that would help.

BTW I am unsure whether or not this is really a plist since afaik they are xml structured, even though I have heard of json like structured ones before I was never able to obtain a official documentation letalone a parser, I guess its an apple internal file format.
the format is not a plist per se, ie, it's probably (just my guess) an unstable textual representation of internal structures such as CFDIctionary which can have nested dictionaries and NSArray types. Looks like Apple intentionally did not use a format like json or xml in order to prevent users relying on the shape of that output.
If you look at man launchctl you'll see this section:
CAVEATS
The output produced by the "legacy" subcommands (chiefly list) should
match their output on previous OS X releases. However, the output of
newer subcommands does not conform to any particular format and is not
guaranteed to remain stable across releases. These commands are intended
for use by human developers and system administrators, not for automation
by programs or scripts. Their output does not constitute an API and no
promises of forward compatibility are offered to programs that attempt to
parse it.
confirming that filtering works on ventura with latest push; there are still 4 indexed array index operations after split with no check for number of elements — could you please add checks for the length of the chunks to make sure it doesn't throw an index access error when preconditions fail?
I'd also consider adding if 'properties = ' in details:.. and if 'system service = ' in properties:.. to make it failsafe.