You are not logged in.
Hi,
I realize that this might be a very stupid question, but searches on google and the forums have not yielded me an answer for this simple problem:
I want the process list of a systemd unit - just like systemctl status $unitname does - but in machine-readable output, to look for specific processes.
E.g. instead of this
● session-c43.scope - Session c43 of user gigadoc2
Loaded: loaded (/run/systemd/system/session-c43.scope; static)
Drop-In: /run/systemd/system/session-c43.scope.d
└─50-After-systemd-logind\x2eservice.conf, 50-After-systemd-user-sessions\x2eservice.conf, 50-Description.conf, 50-SendSIGHUP.conf, 50-Slice.conf
Active: active (running) since Mo 2014-10-20 02:49:53 CEST; 3min 19s ago
CGroup: /user.slice/user-16776.slice/session-c43.scope
├─12894 sshd: gigadoc2 [priv]
├─12899 sshd: gigadoc2@pts/1
├─12900 -bash
└─12936 systemctl status session-c43.scope
Okt 20 02:49:53 cappuccino sshd[12894]: Accepted publickey for gigadoc2 from [redacted] port 38955 ss...e:80:a6
Okt 20 02:49:53 cappuccino sshd[12894]: pam_unix(sshd:session): session opened for user gigadoc2 by (uid=0)
Hint: Some lines were ellipsized, use -l to show in full.
I want something like this:
12894 sshd: gigadoc2 [priv]
12899 sshd: gigadoc2@pts/1
12900 -bash
12936 systemctl status session-c43.scope
Or, better yet, this:
sshd
sshd
bash
systemctl
Currently I can think of two methods to achieve this:
Firstly, I could just cut out the middle part of the systemctl status output, and then grep for what I am looking for. However, systemctl status is meant for humans to read and might be subject to change without warning. Also, it is kind of ugly.
The other method would look something like this:
ps -o comm= -p $(tr '\n' , < /sys/fs/cgroup/systemd/"$(systemctl show session-c43.scope --property ControlGroup | cut -d = -f 2-)"/cgroup.procs | sed 's/,$//')
which basically gets the cgroup path from systemctl and then transforms the PIDs to process names using ps and a bunch of other commands. This is ugly as well, and IIRC the way cgroups are exposed trough sysfs will change in the future as well.
So, does anyone know a nicer way to get this kind of output?
Offline
This one may not be any less ugly, but it uses cgm from the community/cgmanager package to future proof against sysfs changes.
#!/bin/sh
unit="$1"
cg=$(systemctl show --property ControlGroup "${unit}" | cut -d '=' -f2)
pidlist=$(cgm gettasksrecursive name=systemd "${cg}")
ps -h -o comm --pid ${pidlist}
Note that the cgmanager daemon has to be running for the cgm frontend to work.
Offline
something like this?
systemctl status session-c43.scope | awk 'BEGIN{CG=0; print""} {if ($1=="CGroup:") CG=1; else if (CG==1) if ($1~/[├└─]/) {gsub(/[├└─]/,"",$1); print;}} END {print""}'
Offline
This one may not be any less ugly, but it uses cgm from the community/cgmanager package to future proof against sysfs changes.
#!/bin/sh unit="$1" cg=$(systemctl show --property ControlGroup "${unit}" | cut -d '=' -f2) pidlist=$(cgm gettasksrecursive name=systemd "${cg}") ps -h -o comm --pid ${pidlist}
AFAIK, in the future only one daemon will be able to access cgroups, wich, on Arch, will most likely be systemd. As such, I am not sure whether this solution will work "indefinitely" either. It would be better than directly interacting with sysfs, though.
something like this?
systemctl status session-c43.scope | awk 'BEGIN{CG=0; print""} {if ($1=="CGroup:") CG=1; else if (CG==1) if ($1~/[├└─]/) {gsub(/[├└─]/,"",$1); print;}} END {print""}'
This looks like my first solution. It would work for now, but since systemctl status is explicitly designed for human interaction only, the specific formatting might change without warning.
Offline