Files
dasandClaude Opus 5.5 e01e1786d6
build / build (push) Successful in 23m2s
Terminal: Das OS aliases and functions (0.9.3)
- 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>
2026-10-21 19:35:58 +03:00

375 lines
13 KiB
Bash
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 "$@"
}