3

My situation

I installed a few new unit files under $HOME/.local/share/systemd/user/

ls -1 $HOME/.local/share/systemd/user/
some.service
some.timer
some_other.service

I ran the following command to have them loaded properly: systemctl --user daemon-reload

They show up in auto completion of systemctl --user enable <tab> <tab>. What I'm looking for is a way to later write a script with gum to show me a list of those units which are currently not enabled to enable them.

My question

Is there a better way than ls -1 $HOME/.local/share/systemd/user/ to get the list I'm looking for?

systemctl knows about the units through auto completion, but I don't want to that deep for a seemingly rather simple question. I looked at systemctl list all possible (including disabled) services and some parts of the Systemd documentation, but I wasn't able to find what I was looking for yet. It doesn't have to be perfect, the auto complete list also has some other entries which I could filter out. That won't be a problem for me.

0

2 Answers 2

6

In general, systemctl --user list-unit-files shows the list of all user services.

So you can run the following command in order to get the list of user services that are disabled:

systemctl --user --full --no-legend --no-pager list-unit-files --state=disabled

By the way, you can look at the bash completion file of systemctl to see how it gets the list of disabled services, which is very similar:


__systemctl() {
    local mode=$1; shift 1
    systemctl $mode --full --legend=no --no-pager --plain "$@" 2>/dev/null
}

[...]

__get_disabled_units() { __systemctl $1 list-unit-files "$2*" \
                              | while read -r a b c  ; do [[ $b == "disabled" ]] && echo " $a"; done; }

You can also find this file on your local machine. In my case it's located at /usr/share/bash-completion/completions/systemctl, but I'm not sure if it's the standard path for all disros.

1
  • Thank you! I was wondering what kind of magic would be at play. Now I see that echo " $a" outputs the first column (= unit file name). Ok, now I don't have to feel ashamed for using awk {print $1} to get what I want. The path to bash completers should be pretty much standardized in distributions which integrate Systemd. For Ubuntu it is packages.ubuntu.com/noble/amd64/systemd/filelist the same, for other distributions the quickest way I know of would be pkgs.org/search/?q=systemd&on=files and looking at the file list. :-)
    – LiveWireBT
    Commented Jan 23 at 0:39
5

aviro's answer motivated me to spend a bit more time on this. This is what I came up with now:

SYSTEMD_COLORS=no systemctl list-unit-files \
    --full \
    --no-legend \
    --no-pager \
    --state=disabled \
    --type=service,timer \
    --user \
| sort \
| awk '!/^(obex|rygel|wireplumber)(@)?\.(service|timer)/ {print $1}'
  • You don't need SYSTEMD_COLORS=no, systemctl itself should detect that its output is sent to a pipe, but I leave it here for readers who will be further experimenting with the code.

  • I included --type=service,timer because I had at least one .socket unit in my list.

  • obex|rygel|wireplumber is a list of units I don't want to have in the selection. If you want to use an allow list instead of a deny list, you need to remove ! at the beginning.

As I wrote in my question, I further process this with gum, so awk is followed by | gum choose in my script. It makes sense when you look at the project's site.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .