···11+BSD Zero Clause License
22+33+Copyright (c) 2025 Mario Nachbaur
44+55+Permission to use, copy, modify, and/or distribute this software for any
66+purpose with or without fee is hereby granted.
77+88+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
99+REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
1010+AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
1111+INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
1212+LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
1313+OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
1414+PERFORMANCE OF THIS SOFTWARE.
+30
README.md
···11+# status
22+33+A very barebones command to see systemd services status.
44+55+```sh
66+$ status
77+ssh active enabled
88+caddy active enabled
99+service inactive enabled
1010+```
1111+1212+## config
1313+1414+Create a file in `$XDG_CONFIG_HOME/statusrc` or `$HOME/.config/statusrc` with a service name per line, eg:
1515+1616+```
1717+ssh
1818+caddy
1919+your-service-name
2020+```
2121+2222+Lines starting with `#` will be ignored.
2323+2424+## usage
2525+2626+Just run `status`.
2727+2828+## install
2929+3030+Move the `status` script to your `$PATH`.
+56
status
···11+#!/usr/bin/env python3
22+33+from logging import Logger
44+from os import getenv
55+from pathlib import Path
66+from subprocess import PIPE, run
77+88+logger = Logger(__name__)
99+1010+1111+def main():
1212+ services = read_services()
1313+ if not services:
1414+ return
1515+ actives = get("is-active", services)
1616+ enabled = get("is-enabled", services)
1717+ row_format = f"{{:{1 + max(map(len, services))}}}{{:{1 + max(map(len, actives))}}}{{:{1 + max(map(len, enabled))}}}"
1818+ for index, service in enumerate(services):
1919+ print(row_format.format(service, actives[index], enabled[index]))
2020+2121+2222+def read_services() -> list[str]:
2323+ config = find_configuration()
2424+ if config is None:
2525+ return []
2626+ path = Path(config)
2727+ if not path.exists():
2828+ logger.warning(f"No configuration file found at {path}")
2929+ return []
3030+ with open(config, "r") as file:
3131+ return list(
3232+ filter(
3333+ lambda x: not x.startswith("#"),
3434+ map(lambda s: s.strip(), file.readlines()),
3535+ ),
3636+ )
3737+3838+3939+def find_configuration() -> str | None:
4040+ xdg = getenv("XDG_CONFIG_HOME")
4141+ if xdg:
4242+ return f"{xdg}/statusrc"
4343+ home = getenv("HOME")
4444+ if home:
4545+ return f"{home}/.config/statusrc"
4646+ return None
4747+4848+4949+def get(subcommand: str, services: list[str]) -> list[str]:
5050+ command = ["systemctl", subcommand] + services
5151+ result = run(command, stdout=PIPE)
5252+ return result.stdout.decode("utf-8").splitlines()
5353+5454+5555+if __name__ == "__main__":
5656+ main()