📦 unit-suffix-remover (unsure)
Python CLI to stop, disable, and remove systemd
.timerand.serviceunits by suffix. 🔧🧹
🧭 How it works
flowchart TD
A["unsure -s SUFFIX"] --> B["list *.service and *.timer in the unit dir"]
B --> C{"name is PREFIX.SUFFIX with an optional @INSTANCE?"}
C -- no --> B
C -- yes --> D["collect the unit"]
D --> E{"any unit collected?"}
E -- no --> Y["No matching units found - exit 0"]
E -- yes --> F{"--dry-run?"}
F -- yes --> G["announce the removal, change nothing"]
F -- no --> H["systemctl stop"]
H --> I["systemctl disable"]
I --> J["delete the unit file"]
J --> K["systemctl daemon-reload"]
G --> Z["exit 0"]
K --> Z
🚀 Installation
pip install unit-suffix-remover
pip is the single supported installation path.
The package installs two identical commands: unsure (primary) and usure (kept for older documentation and scripts).
🔧 Requirements
- Python 3.10+ 🐍
systemctlonPATH(systemd)
If systemctl is missing, the command exits with code 127 and a one‑line error instead of a traceback.
⚙️ Usage
unsure -s SUFFIX [--dry-run] [--unit-dir DIR]
-s,--suffix: suffix of unit files to target (e.g.infinitofor*.infinito.timerand*.infinito.service). Required.-d,--dry-run: show actions without executing them.--unit-dir: directory to scan. Defaults to/etc/systemd/system.
Only the exact suffix directly before @ or the extension matches:
| Unit file | -s infinito |
|---|---|
web.infinito.service |
✅ matched |
web.infinito@db.timer |
✅ matched |
web.infinito.nexus.timer |
❌ extra part after the suffix |
web@db.infinito.timer |
❌ suffix sits after @ |
web.infinitoX.service |
❌ suffix is only a prefix |
For full options:
unsure --help
Exit codes
| Code | Meaning |
|---|---|
0 |
Finished, or nothing matched. |
2 |
Invalid command line arguments. |
127 |
A required command is not installed. |
🧪 Development
make lint # ruff check + ruff format --check
make format # apply ruff format
make test # unit + integration tests
make test-unit
make test-integration
make test-e2e # install the package in a container and exercise the CLI
Tests run against the working tree — the Makefile puts src/ on PYTHONPATH, so no install is needed. --unit-dir lets the integration tests work on a temporary directory instead of /etc/systemd/system.
👤 Author
Developed by Kevin Veen‑Birkenbach 🌐 veen.world
📜 License
This project is licensed under the MIT License.
Metadata
Release files for unit-suffix-remover 1.0.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| unit_suffix_remover-1.0.1.tar.gz | 9.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| unit_suffix_remover-1.0.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 15.8 kB
Release files / unit_suffix_remover-1.0.1.tar.gz
| Download URL | unit_suffix_remover-1.0.1.tar.gz |
|---|---|
| Size | 9.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
28bfdc182d537677e9cef1b3e039e5cd70046ad6036bdc765045916794b8423d
|
|
BLAKE2b-256 checksum How to use checksums |
32cdf27dcca7a7c5dd0bb80140b84d0cab87716f632f18a57957d603aadf6087
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.6
|
Release files / unit_suffix_remover-1.0.1-py3-none-any.whl
| Download URL | unit_suffix_remover-1.0.1-py3-none-any.whl |
|---|---|
| Size | 6.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
0c6c1de8cd28935842a438fa8f5ec7b40a0af01ae67a953609a3e0827bd8dc55
|
|
BLAKE2b-256 checksum How to use checksums |
d79a3c5e04748130eeeef7ab2eb55a19e559d03bc15015b1245b234ba258a769
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.6
|