Terminal: Das OS aliases and functions (0.9.3)
build / build (push) Successful in 23m2s

- das-shell 0.3.0: aliases and functions for every interactive bash
  (/usr/share/das/shell, loaded by /etc/bash/bashrc.d/das-aliases.sh,
  then the user's ~/.bash_aliases and ~/.bash_functions; off with
  ~/.config/das/no-aliases). Based on the author's own set, adapted to
  Void (xbps, nftables, das-update), with fixes (rmhost, netinfo,
  todo -r, dirsize, extract) and new ones (up, bigfiles, pkgowner,
  please, serve, weather, cheat, genpass, Docker shortcuts). lsfunc
  shows bilingual descriptions. Shell tests in tests/test_shell.py.
- Names that shadowed commands are gone: gh -> hgrep, mount -> mounts,
  no install or ed.
- README: "Aliases and functions" section; TODO: banner, dashboard
  service and prompt verified by the author on real hardware.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
das
2026-10-21 19:35:58 +03:00
co-authored by Claude Opus 5.5
parent 6564d1eb17
commit e01e1786d6
9 changed files with 580 additions and 12 deletions
+18 -3
View File
@@ -1,7 +1,7 @@
## Das OS ## Das OS
### _A light, friendly Void Linux–based desktop with Xfce and a Ukrainian touch, plus a console server edition_ ### _A light, friendly Void Linux–based desktop with Xfce and a Ukrainian touch, plus a console server edition_
[![Void Linux](https://img.shields.io/badge/Void_Linux-x86__64_glibc-green)](https://voidlinux.org) [![Xfce](https://img.shields.io/badge/Xfce-4.20-orange)](https://xfce.org) [![runit](https://img.shields.io/badge/init-runit-blue)](https://docs.voidlinux.org/config/services/) [![Go](https://img.shields.io/badge/Go-1.24+-blue)](https://go.dev) [![Docker](https://img.shields.io/badge/Docker-29-blue)](https://www.docker.com) [![Python](https://img.shields.io/badge/Python-3-blue)](https://www.python.org) [![Textual](https://img.shields.io/badge/Textual-8.2-blue)](https://textual.textualize.io) [![Version](https://img.shields.io/badge/version-0.9.2-lightgrey)](#) [![Void Linux](https://img.shields.io/badge/Void_Linux-x86__64_glibc-green)](https://voidlinux.org) [![Xfce](https://img.shields.io/badge/Xfce-4.20-orange)](https://xfce.org) [![runit](https://img.shields.io/badge/init-runit-blue)](https://docs.voidlinux.org/config/services/) [![Go](https://img.shields.io/badge/Go-1.24+-blue)](https://go.dev) [![Docker](https://img.shields.io/badge/Docker-29-blue)](https://www.docker.com) [![Python](https://img.shields.io/badge/Python-3-blue)](https://www.python.org) [![Textual](https://img.shields.io/badge/Textual-8.2-blue)](https://textual.textualize.io) [![Version](https://img.shields.io/badge/version-0.9.3-lightgrey)](#)
🇺🇦 [Українська версія](README_ua.md) 🇺🇦 [Українська версія](README_ua.md)
@@ -17,6 +17,7 @@ Void Linux is fast, simple and independent: runit instead of systemd, and its ow
- [Server image](#Server): a console live ISO with a text installer, SSH, firewall, fail2ban and Docker - [Server image](#Server): a console live ISO with a text installer, SSH, firewall, fail2ban and Docker
- [Command-line helpers](#Helpers) for everyday admin tasks: services (`dsv`), users (`duser`), firewall (`dfw`) and system settings (`dsys`) - [Command-line helpers](#Helpers) for everyday admin tasks: services (`dsv`), users (`duser`), firewall (`dfw`) and system settings (`dsys`)
- [Terminal prompt and SSH login banner](#Terminal): the Das prompt by default, the `dprompt` prompt builder and the `dbanner` banner editor with the Das OS logo and the tryzub - [Terminal prompt and SSH login banner](#Terminal): the Das prompt by default, the `dprompt` prompt builder and the `dbanner` banner editor with the Das OS logo and the tryzub
- [Aliases and functions](#Aliases) for every terminal: `extract`, `mkcd`, `netinfo`, `pkgowner`, Docker shortcuts and more, with `lsfunc` to list them
- [Developer profile](#DevProfile) in one command: Go, Python, Node.js, Docker, rootless Podman, VS Code and IDEs from Flathub - [Developer profile](#DevProfile) in one command: Go, Python, Node.js, Docker, rootless Podman, VS Code and IDEs from Flathub
- [Das OS look](#Look): light and dark themes, generated window frames, wallpapers and logo - [Das OS look](#Look): light and dark themes, generated window frames, wallpapers and logo
- [Desktop defaults](#Defaults) for Xfce that don't overwrite stock files - [Desktop defaults](#Defaults) for Xfce that don't overwrite stock files
@@ -135,7 +136,7 @@ Void Linux is fast, simple and independent: runit instead of systemd, and its ow
- The installed system runs `sshd`, `chronyd`, `nftables`, `fail2ban`, `docker`, `socklog` and the chosen network service. - The installed system runs `sshd`, `chronyd`, `nftables`, `fail2ban`, `docker`, `socklog` and the chosen network service.
- nftables lets in only SSH, ICMP and DHCPv6 (`/etc/nftables.conf`), more ports are opened with `dfw`. The rules live in their own table `inet das`, so reloading them keeps the Docker and fail2ban rules. Ports that containers publish pass through Docker's own rules. - nftables lets in only SSH, ICMP and DHCPv6 (`/etc/nftables.conf`), more ports are opened with `dfw`. The rules live in their own table `inet das`, so reloading them keeps the Docker and fail2ban rules. Ports that containers publish pass through Docker's own rules.
- fail2ban bans addresses that keep failing SSH logins, reading the socklog log. sshd doesn't accept root password logins. - fail2ban bans addresses that keep failing SSH logins, reading the socklog log. sshd doesn't accept root password logins.
- Tools: Docker with Compose, lazydocker, lazygit, Midnight Commander, tmux, htop, ncdu, Python 3, curl, `das-update --cli`, the [helpers](#Helpers), [`dprompt` and `dbanner`](#Terminal) and xtools (`xi`, `xq`, `xrs`). There are no graphical libraries, and no firmware for NVIDIA graphics or sound cards (`/etc/xbps.d/das-server.conf` keeps updates from bringing it back). - Tools: Docker with Compose, lazydocker, lazygit, Midnight Commander, tmux, htop, ncdu, Python 3, curl, `das-update --cli`, the [helpers](#Helpers), [`dprompt` and `dbanner`](#Terminal), [aliases and functions](#Aliases) and xtools (`xi`, `xq`, `xrs`). There are no graphical libraries, and no firmware for NVIDIA graphics or sound cards (`/etc/xbps.d/das-server.conf` keeps updates from bringing it back).
#### Command-line helpers<a id='Helpers' /> #### Command-line helpers<a id='Helpers' />
**_Short commands for tasks that systemd distributions handle with systemctl, hostnamectl and the like, and that Void leaves to manual editing._** **_Short commands for tasks that systemd distributions handle with systemctl, hostnamectl and the like, and that Void leaves to manual editing._**
@@ -160,6 +161,20 @@ Void Linux is fast, simple and independent: runit instead of systemd, and its ow
- Quick widgets run at login with a short timeout. Slow or root-only ones (updates, weather, SMART, fail2ban) are refreshed by the `das-banner` runit service into `/var/cache/das/banner`, and `dbanner apply` enables it when a banner needs it. No cron is needed. - Quick widgets run at login with a short timeout. Slow or root-only ones (updates, weather, SMART, fail2ban) are refreshed by the `das-banner` runit service into `/var/cache/das/banner`, and `dbanner apply` enables it when a banner needs it. No cron is needed.
- Drafts are kept in `~/.config/das/banner`; Ctrl+A or `dbanner apply NAME` writes `/etc/das/banner.json` through sudo. `dbanner off` and `on` turn the banner off for everyone, `~/.hushlogin` for one user; `"local": true` shows it on console logins too. - Drafts are kept in `~/.config/das/banner`; Ctrl+A or `dbanner apply NAME` writes `/etc/das/banner.json` through sudo. `dbanner off` and `on` turn the banner off for everyone, `~/.hushlogin` for one user; `"local": true` shows it on console logins too.
#### Aliases and functions<a id='Aliases' />
**_Ready shortcuts for everyday terminal work in every interactive bash, rewritten for Void: xbps, nftables, runit and Docker._**
- They come from `/etc/bash/bashrc.d/das-aliases.sh` (package `das-shell`): `/usr/share/das/shell/aliases.sh` and `functions.sh`, then your own `~/.bash_aliases` and `~/.bash_functions`, which win. `touch ~/.config/das/no-aliases` turns the Das OS ones off for one user. `lsfunc` lists the functions with a description in the user's language, `alias` lists the aliases.
- `ls`: `ll`, `la`, `l`, `sl`, `lsl` (in `less`), `lsz` (by size), `lst` (by time), `lsd` (directories only); `grep`, `diff` and `ip` in colour.
- Directories: `..`, `...`, `....`, `cd..`, `up [N]` (N levels up), `mkcd DIR` (create and enter), `cl DIR` (enter and list), `path` (one `PATH` entry per line); `mkdir` makes parents.
- Files: `f PATTERN [DIR]` (find by name, any case), `fhere NAME`, `cnt` (number of files), `bigfiles [DIR] [N]`, `dirsize [DIR]` (sizes of everything in a directory), `whatsize [DIR]` (subdirectory sizes, `/` by default), `bu FILE...` (copy with the date in the name), `ednt FILE` (edit keeping the modification time).
- Archives: `extract ARCHIVE...` unpacks tar of any compression, `.xbps`, zip, rar, 7z, gz, bz2, xz, zst, lz4 and Z; `compress NAME.tar.gz|tar.xz|tar.zst|zip|7z FILE...` packs by the name's extension. A missing tool is named together with the package to install.
- Disks and memory: `df`, `dft` (with types and a total), `dftl`, `mnt` (mounted devices), `mounts`, `devid` (lsblk, blkid and lsusb), `snaps` (root snapshots), `free`, `meminfo`, `cpuinfo`, `gpumeminfo`.
- Processes and history: `psa TEXT`, `pst TEXT` (as a tree), `psg`, `psmem`/`psmem10`, `pscpu`/`pscpu10`, `j`, `hgrep TEXT`, `histat [N]` and `histop10` (most used commands), `EC` (the previous exit code), `please` (the previous command again with sudo).
- Packages: `upd` and `updy` (`das-update --cli` with snapshots, `updy` without questions), `pkgshow [TEXT]` (installed), `pkgfind TEXT` (in the repositories), `pkgowner FILE|COMMAND`, `pkgclean` (package cache and orphans).
- Network: `myip`, `netinfo` (addresses, gateway, DNS, public IP), `oports` and `gport TEXT` (listening ports), `ping5`, `fastping`, `header URL` and `headerc URL` (HTTP headers, with compression), `listen PORT`, `serve [PORT]` (the current directory over HTTP), `rmhost HOST|LINE` (clean `known_hosts`), `nftlist`, `firewall` (`dfw status`), `weather [CITY]`, `cheat COMMAND` (cheat.sh).
- Docker: `dps`, `dlog CONTAINER`, `dcu`, `dcd`, `dcl`, `dcp` (compose up, down, logs, pull), `lzd`, `lzg`.
- Small tools: `calc EXPR`, `epoch [SECONDS]`, `genpass [LENGTH]`, `now`, `nowdate`, `note [-c] [TEXT]` (`~/.notes`), `todo [-l|-r N|-c] [TEXT]` (`~/.todo`), `csrc FILE.c` (compile and run C), `man` with coloured headings.
#### Developer profile<a id='DevProfile' /> #### Developer profile<a id='DevProfile' />
**_`dprofile install dev` turns a desktop or a server into a development machine, with a snapshot taken before it._** **_`dprofile install dev` turns a desktop or a server into a development machine, with a snapshot taken before it._**
- Packages from the Void repository: `base-devel`, gdb, strace, Git with LFS, GitHub CLI, lazygit, Go with gopls, delve and golangci-lint, Python with pip, virtualenv and uv, Node.js, Docker with Compose and Buildx, lazydocker, Podman with podman-compose, jq, ripgrep, fd, fzf, direnv, shellcheck and SQLite. - Packages from the Void repository: `base-devel`, gdb, strace, Git with LFS, GitHub CLI, lazygit, Go with gopls, delve and golangci-lint, Python with pip, virtualenv and uv, Node.js, Docker with Compose and Buildx, lazydocker, Podman with podman-compose, jq, ripgrep, fd, fzf, direnv, shellcheck and SQLite.
@@ -222,6 +237,6 @@ make clean # remove build output, keep the download cache
``` ```
The ISOs appear in `out/iso/dasos-<version>-x86_64.iso` and `out/iso/dasos-server-<version>-x86_64.iso`. Write them to a USB stick with `dd` or Ventoy. For a Ventoy theme there is a 48×48 menu icon `live/branding/ventoy/dasos.png`: copy it to the theme's `icons/` folder and add `{ "key": "dasos", "class": "dasos" }` to `menu_class` in `ventoy.json`. The ISOs appear in `out/iso/dasos-<version>-x86_64.iso` and `out/iso/dasos-server-<version>-x86_64.iso`. Write them to a USB stick with `dd` or Ventoy. For a Ventoy theme there is a 48×48 menu icon `live/branding/ventoy/dasos.png`: copy it to the theme's `icons/` folder and add `{ "key": "dasos", "class": "dasos" }` to `menu_class` in `ventoy.json`.
**Note:** Das OS is an early version (0.9.2). Packages and ISOs are built in CI; signed repository hosting is planned for an upcoming stage. Until the repository is hosted, an installed system gets updates from Void only. Das OS is based on Void Linux but is not affiliated with it. **Note:** Das OS is an early version (0.9.3). Packages and ISOs are built in CI; signed repository hosting is planned for an upcoming stage. Until the repository is hosted, an installed system gets updates from Void only. Das OS is based on Void Linux but is not affiliated with it.
###### _Made by -=:dAs:=-_ ###### _Made by -=:dAs:=-_
+18 -3
View File
@@ -1,7 +1,7 @@
## Das OS ## Das OS
### _Легкий і дружній десктоп на базі Void Linux з Xfce та українським колоритом, а також консольна серверна версія_ ### _Легкий і дружній десктоп на базі Void Linux з Xfce та українським колоритом, а також консольна серверна версія_
[![Void Linux](https://img.shields.io/badge/Void_Linux-x86__64_glibc-green)](https://voidlinux.org) [![Xfce](https://img.shields.io/badge/Xfce-4.20-orange)](https://xfce.org) [![runit](https://img.shields.io/badge/init-runit-blue)](https://docs.voidlinux.org/config/services/) [![Go](https://img.shields.io/badge/Go-1.24+-blue)](https://go.dev) [![Docker](https://img.shields.io/badge/Docker-29-blue)](https://www.docker.com) [![Python](https://img.shields.io/badge/Python-3-blue)](https://www.python.org) [![Textual](https://img.shields.io/badge/Textual-8.2-blue)](https://textual.textualize.io) [![Version](https://img.shields.io/badge/version-0.9.2-lightgrey)](#) [![Void Linux](https://img.shields.io/badge/Void_Linux-x86__64_glibc-green)](https://voidlinux.org) [![Xfce](https://img.shields.io/badge/Xfce-4.20-orange)](https://xfce.org) [![runit](https://img.shields.io/badge/init-runit-blue)](https://docs.voidlinux.org/config/services/) [![Go](https://img.shields.io/badge/Go-1.24+-blue)](https://go.dev) [![Docker](https://img.shields.io/badge/Docker-29-blue)](https://www.docker.com) [![Python](https://img.shields.io/badge/Python-3-blue)](https://www.python.org) [![Textual](https://img.shields.io/badge/Textual-8.2-blue)](https://textual.textualize.io) [![Version](https://img.shields.io/badge/version-0.9.3-lightgrey)](#)
🇬🇧 [English version](README.md) 🇬🇧 [English version](README.md)
@@ -17,6 +17,7 @@ Void Linux швидкий, простий і незалежний: runit зам
- [Серверний образ](#Server): консольний live ISO з текстовим інсталятором, SSH, файрволом, fail2ban і Docker - [Серверний образ](#Server): консольний live ISO з текстовим інсталятором, SSH, файрволом, fail2ban і Docker
- [Консольні помічники](#Helpers) для щоденного адміністрування: служби (`dsv`), користувачі (`duser`), брандмауер (`dfw`) і системні налаштування (`dsys`) - [Консольні помічники](#Helpers) для щоденного адміністрування: служби (`dsv`), користувачі (`duser`), брандмауер (`dfw`) і системні налаштування (`dsys`)
- [Запрошення терміналу й банер при вході по SSH](#Terminal): запрошення Das за замовчуванням, конструктор запрошень `dprompt` і редактор банера `dbanner` з логотипом Das OS і тризубом - [Запрошення терміналу й банер при вході по SSH](#Terminal): запрошення Das за замовчуванням, конструктор запрошень `dprompt` і редактор банера `dbanner` з логотипом Das OS і тризубом
- [Аліаси й функції](#Aliases) у кожному терміналі: `extract`, `mkcd`, `netinfo`, `pkgowner`, скорочення для Docker та інші, а `lsfunc` показує їх список
- [Профіль розробника](#DevProfile) однією командою: Go, Python, Node.js, Docker, rootless Podman, VS Code і середовища з Flathub - [Профіль розробника](#DevProfile) однією командою: Go, Python, Node.js, Docker, rootless Podman, VS Code і середовища з Flathub
- [Оформлення Das OS](#Look): світла й темна теми, згенеровані рамки вікон, шпалери та логотип - [Оформлення Das OS](#Look): світла й темна теми, згенеровані рамки вікон, шпалери та логотип
- [Налаштування за замовчуванням](#Defaults) для Xfce, які не перезаписують стандартні файли - [Налаштування за замовчуванням](#Defaults) для Xfce, які не перезаписують стандартні файли
@@ -135,7 +136,7 @@ Void Linux швидкий, простий і незалежний: runit зам
- Встановлена система запускає `sshd`, `chronyd`, `nftables`, `fail2ban`, `docker`, `socklog` і вибрану мережеву службу. - Встановлена система запускає `sshd`, `chronyd`, `nftables`, `fail2ban`, `docker`, `socklog` і вибрану мережеву службу.
- nftables пропускає лише SSH, ICMP і DHCPv6 (`/etc/nftables.conf`), інші порти відкриває `dfw`. Правила лежать у власній таблиці `inet das`, тож їх перезавантаження не чіпає правил Docker і fail2ban. Порти, які публікують контейнери, проходять через власні правила Docker. - nftables пропускає лише SSH, ICMP і DHCPv6 (`/etc/nftables.conf`), інші порти відкриває `dfw`. Правила лежать у власній таблиці `inet das`, тож їх перезавантаження не чіпає правил Docker і fail2ban. Порти, які публікують контейнери, проходять через власні правила Docker.
- fail2ban блокує адреси, з яких раз у раз не вдається увійти по SSH, читаючи журнал socklog. sshd не приймає вхід root за паролем. - fail2ban блокує адреси, з яких раз у раз не вдається увійти по SSH, читаючи журнал socklog. sshd не приймає вхід root за паролем.
- Інструменти: Docker з Compose, lazydocker, lazygit, Midnight Commander, tmux, htop, ncdu, Python 3, curl, `das-update --cli`, [помічники](#Helpers), [`dprompt` і `dbanner`](#Terminal) та xtools (`xi`, `xq`, `xrs`). Графічних бібліотек немає, як і прошивок для відеокарт NVIDIA та звукових карт (`/etc/xbps.d/das-server.conf` не дає оновленням повернути їх). - Інструменти: Docker з Compose, lazydocker, lazygit, Midnight Commander, tmux, htop, ncdu, Python 3, curl, `das-update --cli`, [помічники](#Helpers), [`dprompt` і `dbanner`](#Terminal), [аліаси й функції](#Aliases) та xtools (`xi`, `xq`, `xrs`). Графічних бібліотек немає, як і прошивок для відеокарт NVIDIA та звукових карт (`/etc/xbps.d/das-server.conf` не дає оновленням повернути їх).
#### Консольні помічники<a id='Helpers' /> #### Консольні помічники<a id='Helpers' />
**_Короткі команди для задач, які в дистрибутивах із systemd розв'язують systemctl, hostnamectl тощо, а у Void доводиться робити вручну._** **_Короткі команди для задач, які в дистрибутивах із systemd розв'язують systemctl, hostnamectl тощо, а у Void доводиться робити вручну._**
@@ -160,6 +161,20 @@ Void Linux швидкий, простий і незалежний: runit зам
- Швидкі віджети виконуються при вході з коротким тайм-аутом. Повільні чи ті, що потребують root (оновлення, погода, SMART, fail2ban), оновлює служба runit `das-banner` у `/var/cache/das/banner`, і `dbanner apply` вмикає її, коли банерові це треба. Cron не потрібен. - Швидкі віджети виконуються при вході з коротким тайм-аутом. Повільні чи ті, що потребують root (оновлення, погода, SMART, fail2ban), оновлює служба runit `das-banner` у `/var/cache/das/banner`, і `dbanner apply` вмикає її, коли банерові це треба. Cron не потрібен.
- Чернетки лежать у `~/.config/das/banner`; Ctrl+A або `dbanner apply НАЗВА` записує `/etc/das/banner.json` через sudo. `dbanner off` і `on` вимикають банер для всіх, `~/.hushlogin` — для одного користувача; `"local": true` показує його й при вході в консоль. - Чернетки лежать у `~/.config/das/banner`; Ctrl+A або `dbanner apply НАЗВА` записує `/etc/das/banner.json` через sudo. `dbanner off` і `on` вимикають банер для всіх, `~/.hushlogin` — для одного користувача; `"local": true` показує його й при вході в консоль.
#### Аліаси й функції<a id='Aliases' />
**_Готові скорочення для щоденної роботи в терміналі в кожному інтерактивному bash, переписані під Void: xbps, nftables, runit і Docker._**
- Їх завантажує `/etc/bash/bashrc.d/das-aliases.sh` (пакет `das-shell`): `/usr/share/das/shell/aliases.sh` і `functions.sh`, а потім ваші `~/.bash_aliases` і `~/.bash_functions`, які мають перевагу. `touch ~/.config/das/no-aliases` вимикає аліаси Das OS для одного користувача. `lsfunc` показує функції з описом мовою користувача, `alias` — аліаси.
- `ls`: `ll`, `la`, `l`, `sl`, `lsl` (у `less`), `lsz` (за розміром), `lst` (за часом), `lsd` (лише каталоги); `grep`, `diff` і `ip` у кольорі.
- Каталоги: `..`, `...`, `....`, `cd..`, `up [N]` (на N рівнів вгору), `mkcd КАТАЛОГ` (створити й перейти), `cl КАТАЛОГ` (перейти й показати), `path` (`PATH` по одному запису в рядку); `mkdir` створює й батьківські каталоги.
- Файли: `f ШАБЛОН [КАТАЛОГ]` (пошук за назвою без регістру), `fhere НАЗВА`, `cnt` (кількість файлів), `bigfiles [КАТАЛОГ] [N]`, `dirsize [КАТАЛОГ]` (розміри всього в каталозі), `whatsize [КАТАЛОГ]` (розміри підкаталогів, типово `/`), `bu ФАЙЛ...` (копія з датою в назві), `ednt ФАЙЛ` (редагувати, зберігши час зміни).
- Архіви: `extract АРХІВ...` розпаковує tar з будь-яким стисненням, `.xbps`, zip, rar, 7z, gz, bz2, xz, zst, lz4 і Z; `compress НАЗВА.tar.gz|tar.xz|tar.zst|zip|7z ФАЙЛ...` пакує за розширенням назви. Якщо бракує програми, функція називає пакет, який треба встановити.
- Диски й пам'ять: `df`, `dft` (з типами й підсумком), `dftl`, `mnt` (змонтовані пристрої), `mounts`, `devid` (lsblk, blkid і lsusb), `snaps` (знімки кореня), `free`, `meminfo`, `cpuinfo`, `gpumeminfo`.
- Процеси й історія: `psa ТЕКСТ`, `pst ТЕКСТ` (деревом), `psg`, `psmem`/`psmem10`, `pscpu`/`pscpu10`, `j`, `hgrep ТЕКСТ`, `histat [N]` і `histop10` (найчастіші команди), `EC` (код попередньої команди), `please` (попередня команда ще раз через sudo).
- Пакети: `upd` і `updy` (`das-update --cli` зі знімками, `updy` без запитань), `pkgshow [ТЕКСТ]` (встановлені), `pkgfind ТЕКСТ` (у репозиторіях), `pkgowner ФАЙЛ|КОМАНДА`, `pkgclean` (кеш пакетів і сироти).
- Мережа: `myip`, `netinfo` (адреси, шлюз, DNS, зовнішня IP), `oports` і `gport ТЕКСТ` (відкриті порти), `ping5`, `fastping`, `header URL` і `headerc URL` (заголовки HTTP, зі стисненням), `listen ПОРТ`, `serve [ПОРТ]` (поточний каталог по HTTP), `rmhost ХОСТ|РЯДОК` (почистити `known_hosts`), `nftlist`, `firewall` (`dfw status`), `weather [МІСТО]`, `cheat КОМАНДА` (cheat.sh).
- Docker: `dps`, `dlog КОНТЕЙНЕР`, `dcu`, `dcd`, `dcl`, `dcp` (compose up, down, logs, pull), `lzd`, `lzg`.
- Дрібні інструменти: `calc ВИРАЗ`, `epoch [СЕКУНДИ]`, `genpass [ДОВЖИНА]`, `now`, `nowdate`, `note [-c] [ТЕКСТ]` (`~/.notes`), `todo [-l|-r N|-c] [ТЕКСТ]` (`~/.todo`), `csrc ФАЙЛ.c` (скомпілювати й запустити C), `man` з кольоровими заголовками.
#### Профіль розробника<a id='DevProfile' /> #### Профіль розробника<a id='DevProfile' />
**_`dprofile install dev` перетворює десктоп чи сервер на машину для розробки, перед цим створивши знімок системи._** **_`dprofile install dev` перетворює десктоп чи сервер на машину для розробки, перед цим створивши знімок системи._**
- Пакети з репозиторію Void: `base-devel`, gdb, strace, Git з LFS, GitHub CLI, lazygit, Go з gopls, delve і golangci-lint, Python з pip, virtualenv і uv, Node.js, Docker з Compose і Buildx, lazydocker, Podman з podman-compose, jq, ripgrep, fd, fzf, direnv, shellcheck і SQLite. - Пакети з репозиторію Void: `base-devel`, gdb, strace, Git з LFS, GitHub CLI, lazygit, Go з gopls, delve і golangci-lint, Python з pip, virtualenv і uv, Node.js, Docker з Compose і Buildx, lazydocker, Podman з podman-compose, jq, ripgrep, fd, fzf, direnv, shellcheck і SQLite.
@@ -222,6 +237,6 @@ make clean # видалити результати збиранн
``` ```
ISO з'являються в `out/iso/dasos-<версія>-x86_64.iso` і `out/iso/dasos-server-<версія>-x86_64.iso`. Записати їх на флешку можна через `dd` або Ventoy. Для теми Ventoy є значок меню 48×48 `live/branding/ventoy/dasos.png`: скопіюйте його в теку `icons/` теми й додайте `{ "key": "dasos", "class": "dasos" }` до `menu_class` у `ventoy.json`. ISO з'являються в `out/iso/dasos-<версія>-x86_64.iso` і `out/iso/dasos-server-<версія>-x86_64.iso`. Записати їх на флешку можна через `dd` або Ventoy. Для теми Ventoy є значок меню 48×48 `live/branding/ventoy/dasos.png`: скопіюйте його в теку `icons/` теми й додайте `{ "key": "dasos", "class": "dasos" }` до `menu_class` у `ventoy.json`.
**Примітка:** Das OS — рання версія (0.9.2). Пакети й ISO збираються в CI; підписаний репозиторій на хостингу заплановано на наступний етап. Поки репозиторій не розміщено на хостингу, встановлена система отримує оновлення лише з Void. Das OS базується на Void Linux, але не пов'язана з ним офіційно. **Примітка:** Das OS — рання версія (0.9.3). Пакети й ISO збираються в CI; підписаний репозиторій на хостингу заплановано на наступний етап. Поки репозиторій не розміщено на хостингу, встановлена система отримує оновлення лише з Void. Das OS базується на Void Linux, але не пов'язана з ним офіційно.
###### _Made by -=:dAs:=-_ ###### _Made by -=:dAs:=-_
+5 -2
View File
@@ -1,6 +1,6 @@
# Das OS — що зробити далі # Das OS — що зробити далі
Стан на 2026-10-21: версія 0.9.2, етапи 1–8 готові (live ISO, власний репозиторій, оформлення, інсталятор Calamares зі знімками Btrfs, Go-утиліти `das-update` і `das-welcome`, серверний образ з консольним інсталятором, менші ISO, консольні помічники, профіль розробника), CI (етап 9: пакети й обидва ISO збираються на власному runner, ~45 хв). Стан на 2026-10-21: версія 0.9.3, етапи 1–8 готові (live ISO, власний репозиторій, оформлення, інсталятор Calamares зі знімками Btrfs, Go-утиліти `das-update` і `das-welcome`, серверний образ з консольним інсталятором, менші ISO, консольні помічники, профіль розробника), CI (етап 9: пакети й обидва ISO збираються на власному runner, ~45 хв).
## Етап 5. Go-утиліти (готово, лишилися перевірки) ## Етап 5. Go-утиліти (готово, лишилися перевірки)
- [x] `das-update`: вікно, значок у треї (лише коли є оновлення), консольний режим `--cli`, знімок snapper pre/post, встановлення через pkexec, підказка про відкат. - [x] `das-update`: вікно, значок у треї (лише коли є оновлення), консольний режим `--cli`, знімок snapper pre/post, встановлення через pkexec, підказка про відкат.
@@ -84,7 +84,10 @@ Live ISO без графіки з консольним інсталятором:
- [x] `dbanner`: кнопки внизу стартового екрана перекривав рядок підказок клавіш (обидва були прикріплені до низу): тепер кнопки — звичайний рядок під списком. - [x] `dbanner`: кнопки внизу стартового екрана перекривав рядок підказок клавіш (обидва були прикріплені до низу): тепер кнопки — звичайний рядок під списком.
- [x] У консолі Linux (`TERM=linux`) рамки кнопок, полів і списків `dprompt`/`dbanner` були квадратиками: Textual малює їх символами `▊▎▔▁`, яких немає в жодному консольному шрифті (до 512 символів; перевірено `cyr-sun16`, `default8x16`, `eurlatgr`, Terminus). Тепер там рамки `┌─┐`, а решта відсутніх символів замінюється на наявні. Символи палітри малювання (★ ☀ ♥…) лишаються як є: це вміст банера для SSH-клієнтів. - [x] У консолі Linux (`TERM=linux`) рамки кнопок, полів і списків `dprompt`/`dbanner` були квадратиками: Textual малює їх символами `▊▎▔▁`, яких немає в жодному консольному шрифті (до 512 символів; перевірено `cyr-sun16`, `default8x16`, `eurlatgr`, Terminus). Тепер там рамки `┌─┐`, а решта відсутніх символів замінюється на наявні. Символи палітри малювання (★ ☀ ♥…) лишаються як є: це вміст банера для SSH-клієнтів.
- [ ] Перевірити `dprompt` і `dbanner` у консолі встановленої системи. - [ ] Перевірити `dprompt` і `dbanner` у консолі встановленої системи.
- [ ] Перевірити в QEMU: сервер — банер при вході по SSH, `dbanner apply dashboard` зі службою, `ssh host cmd` без банера; десктоп — запрошення в xfce4-terminal, обидва редактори. - [x] Аліаси й функції для bash (das-shell 0.3.0, 0.9.3): на основі `~/.bash_aliases` і `~/.bash_functions` автора, переписані під Void (xbps, nftables, `das-update`), з виправленими помилками (`rmhost`, `netinfo`, `todo -r`, `dirsize`, `extract`), двомовними описами для `lsfunc` і новими функціями (`up`, `bigfiles`, `pkgowner`, `please`, `serve`, `weather`, `cheat`, `genpass`, скорочення Docker). Перейменовано те, що затіняло команди: `gh` → `hgrep` (GitHub CLI), `install` прибрано (є `xi`), `mount` → `mounts`, `ed` прибрано.
- [ ] Перевірити аліаси й функції у встановленій системі (desktop і server).
- [x] Перевірено автором на реальному сервері (0.9.1): банер `das-classic` з IP при вході по SSH, свій банер і `dbanner apply ukraine`, `dbanner apply dashboard` вмикає службу `das-banner` (погода й оновлення з'являються), запрошення Das і в SSH, і в консолі (`>` замість `╼`).
- [ ] Перевірити `ssh host cmd` без банера; десктоп — запрошення в xfce4-terminal, обидва редактори.
## Репозиторій пакетів ## Репозиторій пакетів
- [ ] Підпис через `xbps-rindex --sign`, ключ поза репозиторієм. - [ ] Підпис через `xbps-rindex --sign`, ключ поза репозиторієм.
+1 -1
View File
@@ -1 +1 @@
0.9.2 0.9.3
@@ -0,0 +1,18 @@
# Das OS aliases and functions (lsfunc lists the functions), then the user's
# own ~/.bash_aliases and ~/.bash_functions, which win. Off for one user:
# touch ~/.config/das/no-aliases (the user's own files are still read).
# shellcheck shell=bash
if [[ $- == *i* ]]; then
if [[ ! -e ${XDG_CONFIG_HOME:-$HOME/.config}/das/no-aliases ]]; then
for __das_f in /usr/share/das/shell/aliases.sh /usr/share/das/shell/functions.sh; do
# shellcheck source=/dev/null
[[ -r $__das_f ]] && . "$__das_f"
done
fi
for __das_f in ~/.bash_aliases ~/.bash_functions; do
# shellcheck source=/dev/null
[[ -r $__das_f ]] && . "$__das_f"
done
unset __das_f
fi
+85
View File
@@ -0,0 +1,85 @@
# Das OS aliases, loaded by /etc/bash/bashrc.d/das-aliases.sh in interactive
# shells. Your own ~/.bash_aliases is read after this file and wins.
# shellcheck shell=bash
# --- ls ---------------------------------------------------------------------
alias ls='ls --color=auto'
alias sl='ls'
alias l='ls -CF'
alias la='ls -A'
alias ll='ls -alF'
alias lsl='ls -lhFA --color=always | less -R'
alias lsz='ls --human-readable --size -1 -S --classify'
alias lst='ls -t -1'
alias lsd='ls -d */'
alias grep='grep --color=auto'
alias egrep='grep -E --color=auto'
alias fgrep='grep -F --color=auto'
alias diff='diff --color=auto'
alias ip='ip -color=auto'
# --- directories --------------------------------------------------------------
alias ..='cd ..'
alias cd..='cd ..'
alias ...='cd ../..'
alias ....='cd ../../..'
alias mkdir='mkdir -p'
alias path='echo "${PATH//:/$'\''\n'\''}"'
# --- files and disks ----------------------------------------------------------
alias cnt='find . -type f | wc -l'
alias fhere='find . -name'
alias df='df -h'
alias dft='df -Th --total -x tmpfs -x devtmpfs -x efivarfs'
alias dftl='df -Tha --total | less'
alias mounts='mount | column -t'
alias mnt="findmnt -rno SOURCE,TARGET,FSTYPE | grep '^/dev/' | sort | column -t"
alias snaps='sudo snapper -c root list'
# --- memory and processes -----------------------------------------------------
alias free='free -ht'
alias meminfo='command free -mlt'
alias cpuinfo='lscpu'
alias j='jobs -l'
alias psg='ps aux | grep -v grep | grep -i -e VSZ -e'
alias psmem='ps aux --sort=-%mem'
alias psmem10='ps aux --sort=-%mem | head -n 11'
alias pscpu='ps aux --sort=-%cpu'
alias pscpu10='ps aux --sort=-%cpu | head -n 11'
alias gpumeminfo='grep -i --color memory /var/log/Xorg.0.log ~/.local/share/xorg/Xorg.0.log 2>/dev/null'
# --- time ----------------------------------------------------------------------
alias now='date +"%T"'
alias nowtime='now'
alias nowdate='date +"%d-%m-%Y"'
# --- network -------------------------------------------------------------------
alias ping5='ping -c 5'
alias fastping='ping -c 100 -i 0.2'
alias oports='sudo ss -tulpn'
alias gport='sudo ss -tulpn | grep'
alias header='curl -I'
alias headerc='curl -I --compressed'
alias wget='wget -c'
alias nftlist='sudo nft list ruleset'
alias firewall='dfw status'
# --- history --------------------------------------------------------------
alias hgrep='history | grep'
alias histop10='histat 10'
# --- packages and updates (xbps) -------------------------------------------------
alias upd='das-update --cli'
alias updy='das-update --cli -y'
alias pkgclean='sudo xbps-remove -Oo'
# --- Docker and git ----------------------------------------------------------------
alias dps='docker ps --format "table {{.Names}}\t{{.Image}}\t{{.Status}}\t{{.Ports}}"'
alias dlog='docker logs -f --tail 100'
alias dcu='docker compose up -d'
alias dcd='docker compose down'
alias dcl='docker compose logs -f --tail 100'
alias dcp='docker compose pull'
alias lzd='lazydocker'
alias lzg='lazygit'
+374
View File
@@ -0,0 +1,374 @@
# Das OS shell functions, loaded by /etc/bash/bashrc.d/das-aliases.sh in
# interactive shells. Your own ~/.bash_functions is read after this file.
# The first line of each function is its description for lsfunc:
# "# Українською | In English".
# shellcheck shell=bash
__das_uk() {
[[ ${LC_ALL:-${LC_MESSAGES:-${LANG:-}}} == uk* ]]
}
# __das_say UKRAINIAN ENGLISH
__das_say() {
if __das_uk; then echo "$1"; else echo "$2"; fi
}
# __das_usage UKRAINIAN ENGLISH: a usage line on stderr, returns 2
__das_usage() {
__das_say "використання: $1" "usage: $2" >&2
return 2
}
# __das_need COMMAND PACKAGE: is COMMAND there? If not, says which package has it
__das_need() {
command -v "$1" >/dev/null && return 0
__das_say "немає команди $1, встановіть: xi $2" "$1 is missing, install it: xi $2" >&2
return 127
}
lsfunc() {
# Список функцій з описами | List the functions with their descriptions
local name file line descr restore
restore=$(shopt -p extdebug)
shopt -s extdebug
while read -r name; do
[[ $name == _* ]] && continue
read -r _ line file < <(declare -F "$name")
descr=""
if [[ -r $file ]]; then
descr=$(sed -n "$((line + 1)),$((line + 2))p" "$file" | grep -m1 -E '^[[:space:]]*#' |
sed -E 's/^[[:space:]]*#[[:space:]]*//')
fi
if [[ $descr == *" | "* ]]; then
if __das_uk; then descr=${descr%% | *}; else descr=${descr#* | }; fi
fi
printf '%-12s %s\n' "$name" "$descr"
done < <(compgen -A function | sort)
eval "$restore"
}
# --- archives --------------------------------------------------------------------
extract() {
# Розпакувати архіви (tar.*, zip, rar, 7z, gz, xz, zst, xbps…) | Extract archives (tar.*, zip, rar, 7z, gz, xz, zst, xbps…)
(($#)) || { __das_usage "extract АРХІВ..." "extract ARCHIVE..."; return; }
local f rc=0
for f in "$@"; do
if [[ ! -f $f ]]; then
__das_say "'$f' — не файл" "'$f' is not a file" >&2
rc=1
continue
fi
case ${f,,} in
*.tar | *.tar.* | *.tgz | *.tbz | *.tbz2 | *.txz | *.tzst | *.xbps) tar -xvf "$f" ;;
*.zip | *.jar) __das_need unzip unzip && unzip "$f" ;;
*.rar) __das_need unrar unrar && unrar x "$f" ;;
*.7z) __das_need 7z 7zip && 7z x "$f" ;;
*.gz) gunzip -k "$f" ;;
*.bz2) bunzip2 -k "$f" ;;
*.xz) unxz -k "$f" ;;
*.zst) __das_need unzstd zstd && unzstd "$f" ;;
*.lz4) __das_need lz4 lz4 && lz4 -d "$f" ;;
*.z) uncompress "$f" ;;
*)
__das_say "'$f': невідомий тип архіву" "'$f': unknown archive type" >&2
false
;;
esac || rc=1
done
return $rc
}
compress() {
# Запакувати файли в архів; тип за назвою | Pack files into an archive, the type comes from the name
(($# >= 2)) || { __das_usage "compress АРХІВ.tar.gz ФАЙЛ..." "compress ARCHIVE.tar.gz FILE..."; return; }
local archive=$1
shift
case ${archive,,} in
*.tar.gz | *.tgz) tar -czvf "$archive" -- "$@" ;;
*.tar.bz2 | *.tbz2) tar -cjvf "$archive" -- "$@" ;;
*.tar.xz | *.txz) tar -cJvf "$archive" -- "$@" ;;
*.tar.zst | *.tzst) __das_need zstd zstd && tar --zstd -cvf "$archive" -- "$@" ;;
*.tar) tar -cvf "$archive" -- "$@" ;;
*.zip) __das_need zip zip && zip -r "$archive" -- "$@" ;;
*.7z) __das_need 7z 7zip && 7z a "$archive" -- "$@" ;;
*)
__das_say "невідомий тип архіву: $archive (tar.gz, tar.xz, tar.zst, zip, 7z…)" \
"unknown archive type: $archive (tar.gz, tar.xz, tar.zst, zip, 7z…)" >&2
return 1
;;
esac
}
bu() {
# Резервна копія файлу з датою в назві | Back up a file with the date in its name
(($#)) || { __das_usage "bu ФАЙЛ..." "bu FILE..."; return; }
local f stamp
stamp=$(date +%Y%m%d%H%M%S)
for f in "$@"; do
cp -a -- "$f" "$f-$stamp.backup" && echo "$f-$stamp.backup"
done
}
# --- directories and files -----------------------------------------------------------
mkcd() {
# Створити каталог і перейти в нього | Make a directory and go into it
(($# == 1)) || { __das_usage "mkcd КАТАЛОГ" "mkcd DIR"; return; }
mkdir -p -- "$1" && cd -- "$1" || return
}
cl() {
# Перейти в каталог і показати його вміст | Change to a directory and list it
cd -- "${1:-$HOME}" && ls
}
up() {
# Піднятися на N каталогів вгору | Go N directories up
local n=${1:-1} dir=""
[[ $n =~ ^[0-9]+$ ]] || { __das_usage "up [N]" "up [N]"; return; }
while ((n-- > 0)); do dir+="../"; done
cd -- "${dir:-.}" || return
}
f() {
# Знайти файли за назвою (шаблон, без регістру) | Find files by name (a pattern, any case)
(($#)) || { __das_usage "f ШАБЛОН [КАТАЛОГ]" "f PATTERN [DIR]"; return; }
local pattern=$1
[[ $pattern == *[*?[]* ]] || pattern="*$pattern*"
find "${2:-.}" -iname "$pattern" 2>/dev/null
}
dirsize() {
# Розміри всього в каталозі, за зростанням | Sizes of everything in a directory, smallest first
local dir=${1:-.}
du -shx -- "$dir"/* "$dir"/.[!.]* 2>/dev/null | sort -h
}
whatsize() {
# Розміри підкаталогів (типово /) на тій самій ФС, за спаданням | Subdirectory sizes (/ by default) on the same filesystem, largest first
du -hx --max-depth=1 -- "${1:-/}" 2>/dev/null | sort -hr
}
bigfiles() {
# N найбільших файлів у каталозі | The N largest files in a directory
find "${1:-.}" -xdev -type f -printf '%s\t%p\n' 2>/dev/null | sort -nr | head -n "${2:-10}" |
numfmt --to=iec --field=1
}
ednt() {
# Редагувати файл, не змінюючи часу зміни | Edit a file keeping its modification time
(($# == 1)) || { __das_usage "ednt ФАЙЛ" "ednt FILE"; return; }
local mtime
mtime=$(stat -c %y -- "$1") || return
"${VISUAL:-${EDITOR:-vi}}" "$1"
touch -d "$mtime" -- "$1"
}
devid() {
# Пристрої: lsblk, blkid і lsusb разом | Devices: lsblk, blkid and lsusb at once
echo '--- lsblk ---'
lsblk -f -e 7
echo '--- blkid ---'
sudo blkid | grep -v '^/dev/loop'
echo '--- lsusb ---'
lsusb
}
# --- processes and history -------------------------------------------------------------
psa() {
# Процеси, в рядку яких є текст | Processes whose line contains the text
(($#)) || { __das_usage "psa ТЕКСТ" "psa TEXT"; return; }
ps aux | awk -v p="$1" 'NR == 1 || (tolower($0) ~ tolower(p) && !/awk -v p=/)'
}
pst() {
# Те саме деревом процесів | The same as a process tree
(($#)) || { __das_usage "pst ТЕКСТ" "pst TEXT"; return; }
# shellcheck disable=SC2009 # pgrep has no tree
ps auxf | grep -i -B 10 -A 5 -- "$1" | grep -v -e 'grep -i -B' -e 'ps auxf'
}
histat() {
# N найчастіших команд з історії | The N most used commands from history
history | awk -v n="${1:-10}" '
{ sub(/^ *[0-9]+\*? +/, ""); split($0, w, " "); c = w[1]; if (c != "") { cnt[c]++; total++ } }
END { for (c in cnt) printf "%d\t%.1f%%\t%s\n", cnt[c], cnt[c] * 100 / total, c }' |
sort -nr | head -n "${1:-10}" | nl
}
EC() {
# Код завершення попередньої команди | The previous command's exit code
local code=$?
printf '\e[1;33mcode %d\e[m\n' "$code"
return "$code"
}
please() {
# Повторити попередню команду через sudo | Run the previous command again with sudo
local cmd
cmd=$(fc -ln -1)
cmd=${cmd#"${cmd%%[![:space:]]*}"}
echo "sudo $cmd" >&2
sudo bash -c "$cmd"
}
# --- packages (xbps) --------------------------------------------------------------------
pkgshow() {
# Встановлені пакети, з фільтром за назвою | Installed packages, filtered by name
xbps-query -l | awk '{print $2}' | grep -i -- "${1:-.}" | sort
}
pkgfind() {
# Шукати пакети в репозиторіях | Search the repositories for packages
(($#)) || { __das_usage "pkgfind ТЕКСТ" "pkgfind TEXT"; return; }
xbps-query -Rs "$1"
}
pkgowner() {
# Якому пакету належить файл чи команда | Which package owns a file or a command
(($#)) || { __das_usage "pkgowner ФАЙЛ|КОМАНДА" "pkgowner FILE|COMMAND"; return; }
local path=$1
[[ $path == */* ]] || path=$(type -P -- "$1") || path=$1
xbps-query -o "$(readlink -f -- "$path")"
}
# --- network -----------------------------------------------------------------------------
myip() {
# Зовнішня IP-адреса | The public IP address
curl -fsS --max-time 5 https://ifconfig.me/ip && echo
}
netinfo() {
# Адреси, шлюз, DNS і зовнішня IP | Addresses, gateway, DNS and the public IP
echo "--- $(__das_say "Адреси" "Addresses") ---"
command ip -br address | grep -v '^lo '
echo "--- $(__das_say "Шлюз" "Gateway") ---"
command ip route show default
echo "--- DNS ---"
awk '/^nameserver/ {print $2}' /etc/resolv.conf
echo "--- $(__das_say "Зовнішня IP" "Public IP") ---"
myip
}
listen() {
# Слухати порт TCP і показувати, що прийшло | Listen on a TCP port and print what arrives
(($# == 1)) || { __das_usage "listen ПОРТ" "listen PORT"; return; }
__das_need nc openbsd-netcat || return
nc -lvn "$1"
}
rmhost() {
# Прибрати хост або рядок N з ~/.ssh/known_hosts | Remove a host or line N from ~/.ssh/known_hosts
(($# == 1)) || { __das_usage "rmhost ХОСТ|НОМЕР_РЯДКА" "rmhost HOST|LINE_NUMBER"; return; }
if [[ $1 =~ ^[0-9]+$ ]]; then
sed -i.bak "${1}d" ~/.ssh/known_hosts && echo "$HOME/.ssh/known_hosts.bak"
else
ssh-keygen -R "$1"
fi
}
serve() {
# Роздати поточний каталог по HTTP (типово порт 8000) | Serve the current directory over HTTP (port 8000 by default)
__das_need python3 python3 || return
python3 -m http.server "${1:-8000}"
}
weather() {
# Погода з wttr.in (місто з аргументу або за IP) | Weather from wttr.in (the city given, or by IP)
local lang=en
__das_uk && lang=uk
curl -fsS --max-time 10 "https://wttr.in/${1// /+}?lang=$lang"
}
cheat() {
# Шпаргалка до команди з cheat.sh | A command's cheat sheet from cheat.sh
(($#)) || { __das_usage "cheat КОМАНДА" "cheat COMMAND"; return; }
curl -fsS --max-time 10 "https://cheat.sh/$1"
}
# --- small tools -------------------------------------------------------------------------
calc() {
# Порахувати вираз | Calculate an expression
(($#)) || { __das_usage "calc ВИРАЗ" "calc EXPRESSION"; return; }
if command -v bc >/dev/null; then
echo "scale=3; $*" | bc -l
else
awk "BEGIN { print $* }"
fi
}
epoch() {
# Поточний час Unix або перетворити його на дату | The current Unix time, or turn one into a date
if (($#)); then
date -d "@$1" -R
else
date +%s
fi
}
genpass() {
# Випадковий пароль (типово 20 символів) | A random password (20 characters by default)
local n=${1:-20}
[[ $n =~ ^[0-9]+$ ]] || { __das_usage "genpass [ДОВЖИНА]" "genpass [LENGTH]"; return; }
LC_ALL=C tr -dc 'A-Za-z0-9_@%+=.,-' </dev/urandom | head -c "$n"
echo
}
csrc() {
# Скомпілювати й запустити програму на C | Compile and run a C source file
(($#)) || { __das_usage "csrc ФАЙЛ.c [АРГУМЕНТИ]" "csrc FILE.c [ARGS]"; return; }
[[ -r $1 ]] || { __das_say "немає файлу $1" "no such file: $1" >&2; return 1; }
__das_need gcc gcc || return
local src=$1 bin rc
shift
bin=$(mktemp) || return
gcc "$src" -o "$bin" && "$bin" "$@"
rc=$?
rm -f -- "$bin"
return $rc
}
note() {
# Нотатки в ~/.notes: без аргументів показати, -c очистити | Notes in ~/.notes: no arguments shows them, -c clears
local file=$HOME/.notes
if ! (($#)); then
[[ -f $file ]] && cat -- "$file"
elif [[ $1 == -c ]]; then
: >"$file"
else
printf '%s\n' "$*" >>"$file"
fi
}
todo() {
# Справи в ~/.todo: -l з номерами, -r N виконано, -c очистити | To-dos in ~/.todo: -l numbered, -r N done, -c clears
local file=$HOME/.todo
case ${1:-} in
"") [[ -f $file ]] && cat -- "$file" ;;
-l) [[ -f $file ]] && nl -b a -- "$file" ;;
-c) : >"$file" ;;
-r)
local n=${2:-}
if [[ -z $n ]]; then
nl -b a -- "$file"
read -r -p "$(__das_say "Номер, що прибрати: " "Number to remove: ")" n
fi
[[ $n =~ ^[0-9]+$ ]] || return 1
sed -i "${n}d" -- "$file"
;;
*) printf '%s\n' "$*" >>"$file" ;;
esac
}
man() {
# man з кольоровими заголовками | man with coloured headings
LESS_TERMCAP_mb=$'\e[1;31m' LESS_TERMCAP_md=$'\e[1;31m' LESS_TERMCAP_me=$'\e[0m' \
LESS_TERMCAP_so=$'\e[1;44;33m' LESS_TERMCAP_se=$'\e[0m' \
LESS_TERMCAP_us=$'\e[1;32m' LESS_TERMCAP_ue=$'\e[0m' \
GROFF_NO_SGR=1 command man "$@"
}
@@ -0,0 +1,54 @@
import os
import subprocess
import tempfile
import unittest
from tests.common import FILES, SCRATCH
ALIASES = os.path.join(FILES, "shell", "aliases.sh")
FUNCTIONS = os.path.join(FILES, "shell", "functions.sh")
def bash(script, cwd=None):
"""Runs script in bash with the Das OS aliases and functions loaded."""
full = f"shopt -s expand_aliases\n. {ALIASES}\n. {FUNCTIONS}\n{script}"
return subprocess.run(["bash", "--norc", "-c", full], cwd=cwd, capture_output=True, text=True,
env={**os.environ, "HOME": SCRATCH})
class ShellTest(unittest.TestCase):
def test_syntax(self):
for path in (ALIASES, FUNCTIONS, os.path.join(FILES, "bashrc.d", "das-aliases.sh")):
self.assertEqual(subprocess.run(["bash", "-n", path]).returncode, 0, path)
def test_every_function_has_a_description(self):
out = bash("lsfunc").stdout.splitlines()
self.assertIn("extract", [line.split()[0] for line in out])
for line in out:
name, _, descr = line.partition(" ")
self.assertTrue(descr.strip(), f"{name} has no description")
self.assertNotIn(" | ", descr, name)
def test_descriptions_follow_the_language(self):
out = bash("LANG=uk_UA.UTF-8 lsfunc | grep '^mkcd '").stdout
self.assertIn("Створити каталог", out)
def test_compress_and_extract(self):
with tempfile.TemporaryDirectory(dir=SCRATCH) as d:
r = bash("mkdir -p src/sub && echo hi >src/sub/x.txt && compress a.tar.gz src >/dev/null &&"
" mkdir out && cd out && extract ../a.tar.gz >/dev/null && cat src/sub/x.txt", cwd=d)
self.assertEqual(r.stdout, "hi\n", r.stderr)
r = bash("extract nope.zip", cwd=d)
self.assertEqual(r.returncode, 1)
def test_up_and_usage(self):
with tempfile.TemporaryDirectory(dir=SCRATCH) as d:
r = bash("mkcd a/b/c && up 2 && pwd", cwd=d)
self.assertEqual(r.stdout.strip(), os.path.join(os.path.realpath(d), "a"))
r = bash("up x")
self.assertEqual(r.returncode, 2)
self.assertIn("usage: up", r.stderr)
if __name__ == "__main__":
unittest.main()
+7 -3
View File
@@ -1,17 +1,18 @@
# Template file for 'das-shell' # Template file for 'das-shell'
# In-tree package: sources are in files/ (FILESDIR). # In-tree package: sources are in files/ (FILESDIR).
pkgname=das-shell pkgname=das-shell
version=0.2.0 version=0.3.0
revision=1 revision=1
create_wrksrc=yes create_wrksrc=yes
hostmakedepends="python3" hostmakedepends="python3"
checkdepends="bash" checkdepends="bash"
depends="bash python3 python3-textual figlet" depends="bash python3 python3-textual figlet"
short_desc="Das OS terminal: bash prompt, dprompt and dbanner (SSH login banner)" short_desc="Das OS terminal: bash prompt, aliases, dprompt and dbanner (SSH banner)"
maintainer="Das <anry.das@gmail.com>" maintainer="Das <anry.das@gmail.com>"
license="MIT" license="MIT"
homepage="https://git.das.org.ua/das/Das-OS" homepage="https://git.das.org.ua/das/Das-OS"
conf_files="/etc/bash/bashrc.d/das-prompt.sh /etc/profile.d/das-banner.sh" conf_files="/etc/bash/bashrc.d/das-prompt.sh /etc/bash/bashrc.d/das-aliases.sh
/etc/profile.d/das-banner.sh"
make_dirs="/var/cache/das/banner 0755 root root" make_dirs="/var/cache/das/banner 0755 root root"
pycompile_dirs="usr/lib/das/python" pycompile_dirs="usr/lib/das/python"
python_version=3 python_version=3
@@ -29,6 +30,9 @@ do_check() {
do_install() { do_install() {
local f local f
vinstall "${FILESDIR}/bashrc.d/das-prompt.sh" 644 etc/bash/bashrc.d vinstall "${FILESDIR}/bashrc.d/das-prompt.sh" 644 etc/bash/bashrc.d
vinstall "${FILESDIR}/bashrc.d/das-aliases.sh" 644 etc/bash/bashrc.d
vinstall "${FILESDIR}/shell/aliases.sh" 644 usr/share/das/shell
vinstall "${FILESDIR}/shell/functions.sh" 644 usr/share/das/shell
vinstall "${FILESDIR}/profile.d/das-banner.sh" 644 etc/profile.d vinstall "${FILESDIR}/profile.d/das-banner.sh" 644 etc/profile.d
vinstall "${FILESDIR}/prompt-lib.sh" 644 usr/lib/das vinstall "${FILESDIR}/prompt-lib.sh" 644 usr/lib/das
vinstall default-prompt.sh 644 usr/share/das/prompt default.sh vinstall default-prompt.sh 644 usr/share/das/prompt default.sh