Расшарю несколько натасканных мною со всего света полезняшек.
Опубликовано: 2024-06-19
Категория: OpenBSD
Теги: ksh хауту openbsd shell
На заре unix-time, когда, как известно, деревья были большими, трава зеленее, водка крепче только-только зародился этот ваш UNIX, командной оболочкой его стала программа sh, написанная в 1978 году Стефаном Борном. Язык её командного интерпретатора был основан на передовом для тех времен Algol 68, а вот в части интерактивности там был полный швах: никаких столь привычных нам автодополнений путей и команд, средств интерактивного редактирования, истории команд и информативных приглашений там не было и в помине.
Чуть позже расцвела целая клумба шеллов (я не буду сейчас углубляться в подробности, об этом написаны книги, есть сравнительные таблицы...), ограничусь лишь кратким перечислением: в 1980-х в AT&T появился шелл Дэвида Корна ksh, чуть более продвинутый, в университете Беркли зародилась несовместимая по синтаксису скриптов (тяготеющая к языку C) оболочка csh - там-то вроде впервые и возникло большинство современных интерактивных плюшек, ребята из проекта FreeBSD вспомнили про оболочку Кэна Грига из университета Каргени-Меллон tcsh (она создавалась по образу командного интерпретатора ОС TENEX, а отличительной особенностью этой ОС были длиннющие зубодробильные команды, отсюда в tcsh родились наиболее развитые алгоритмы автодополнения и поиска по истории, позднее вошедшие в том или ином виде во все современные шеллы), в мире GNU/Linux начал свое победное шествие bash, в MasOS с некоторых пор стандартной оболочкой стала еще более фичастая zsh...
Но упомянутая мною оболочка Корна ksh заняла место стандартной в AIX и QNX. При этом, код оригинальной ksh до самых 2000-х оставался закрытым, что породило ряд форков - появилась, в частности, pdksh (public domain Korn shell) и вот ее уже много-много лет назад форкнул проект OpenBSD, где ныне ksh и является дефолтной оболочкой в базовой системе. Да, разумеется, в OpenBSD доступны к установке любые другие шеллы из современного (и не очень) зоопарка: bash, zsh, fish, tcsh... Но философия проекта OpenBSD предполагает выбор по умолчанию пусть не самых фичастых, зато простых в устройстве, сопровождении и развитии решений. Поэтому ksh.
Скрипт ~/.kshrc
является одним из умлочальных расположений настроек (другие описаны в man ksh
) и у меня в оный добавлены следующие плюшки:
Экспорт некоторых переменных окружения:
export EDITOR=nvim export VISUAL=nvim export FCEDIT=$EDITOR export PAGER=less export LESS='-iMRS -x2' export LC_CTYPE=en_US.UTF-8 export CLICOLOR=1 export XAUTHORITY=~/.Xauthority export GOPATH=~/go
Настройки расположения и размера файла с историей команд:
HISTFILE=$HOME/.ksh_history HISTSIZE=20000
Стиль редактирования командной строки (поддерживаются emacs-сочетания и режим vi), я хоть и старый вимер, но все-таки хоткеи оболочки въелись в мою плоть и кровь еще раньше освоения vi/vim/nvim, так что:
set -o emacs
Немножко alias для упрощения жизни (думаю, пояснения тут излишни):
alias ls="$LS -FHh" alias ll='ls -l' alias la='ls -lA' alias ..='cd ..' alias ...='cd ...' alias mkdir='mkdir -p' alias df='df -h' alias du='du -ch' alias svim="doas vim" alias svi="doas vi" alias cvsup='cvs -q up -Pd -A' alias nv='nvim' alias snv='doas nvim'
Настройки приглашения командой строки, не перегруженного, но симпатичного (читайте маны, мне эта тарабарщина тоже с трудом дается):
_PID=$$ _XTERM_TITLE='\[\033]0;\u@\w:\w\007\]' _PS1_CLEAR='\[\033[0m\]' _PS1_BLUE='\[\033[34m\]' case "$(id -u)" in 0) _PS1_COLOR='\[\033[1;31m\]' ;; *) _PS1_COLOR='\[\033[32m\]' ;; esac PS1='$_XTERM_TITLE\t $_PS1_COLOR\u$_PS1_CLEAR $_PS1_BLUE\w $_PS1_COLOR\$$_PS1_CLEAR '
Чуть-чуть удобных биндингов: например, вы начали печатать команду, с запозданием вспомнив, что ее нужно запускать от рута? В любой момент нажимаем ESC, затем d - и в начале строки чудесным образом подставляется doas. Второй биндинг для отбитых на голову вимеров, кто периодически пытается выйти из шелла через ":q" :))
bind -m '^[d'='^Adoas ^E' bind -m ':q'='exit^M'
Да вот, пожалуй, и всё. Добавлю лишь, что экспорт ряда переменных окружения, вроде PATH или ENV я держу, по многолетней привычке, в ~/.profile
, а некоторые вещи, специфичные для GUI - в ~/.xsession
.
Теперь к интересному. ksh не располагает такими развесистыми изкоробочными средствами автодополнения, как tcsh, zsh или bash + bash_completion, например, умеет из коробки в автодополнение команд, но если тебе нужно запустить что-то от рута (то есть, ввести сначала doas, а затем команду) - тут облом-с. А еще не умеет в автодополнение по man-страницам. Но решение есть - ksh умеет в автодополнение из файла, так что нам нужно лишь создать файл кеша, содержащий все имена программ и man-страниц для поиска (для удобства я держу нижеприведенный код в отдельном файле ~/scripts/ksh_functions.ksh
:
PROG_CACHE=$HOME/.cache/prog if [ ! -f $PROG_CACHE ]; then mkdir -p $(dirname ${PROG_CACHE}) for directory in $(echo $PATH | tr ':' '\n') do find $directory -type f -perm -111 -exec basename '{}' ';' done | sort -u > $PROG_CACHE fi MAN_CACHE=$HOME/.cache/man if [ ! -f $MAN_CACHE ]; then mkdir -p $(dirname ${MAN_CACHE}) for i in /usr{,/X11R6,/local}{,/share}/man/{,cat,man}[1-9lnp]{,f,p} do test -d $i && ls $i done | rev | cut -d. -f2- | rev | sort -u > $MAN_CACHE fi
Чтобы наполнять этот кеш, создадим в ~/.kshrc
alias (а чтобы не делать этого каждый раз руками после установки/удаления софта, добавим его в crontab):
alias recache='rm -f $HOME/.cache/man && rm -f $HOME/.cache/prog && /bin/ksh -e $HOME/scripts/ksh_functions.ksh' . $HOME/scripts/ksh_functions.ksh
Теперь при каждом запуске ksh или вручную, при вводе команды recache, будут создаваться кеш-файлики со списком всех программ и man-страниц, ну а чтобы по ним работало автодополнение, добавим в ~/.kshrc
вот это:
set -A complete_doas_1 -- $(cat $PROG_CACHE) set -A complete_man -- $(cat $MAN_CACHE)
А вот комфортная автодополнялка для средства запуска служб в OpenBSD: вводишь rcctl, затем уже с возможностью автодополнения управляющую команду, а после, третьим словом (тоже уже с автодополнением) имя службы:
set -A complete_rcctl_1 -- disable enable get ls order set restart start stop set -A complete_rcctl_2 -- $(rcctl ls all)
Есть подобное и для работы с гитом:
set -A complete_git_1 -- \ $(git --list-cmds=main) \ $(git config --get-regexp ^alias\. | awk -F '[\.]' '{ print $2 }')
Еще подсмотренная мною у кого-то полезняшка, быстрая навигация по наиболее употребимым местам в файловой системе. Пишем несложную функцию:
k() { if [ -z $1 ]; then echo $PWD >> ~/.k else K=~/.k case $1 in clean) sort -u $K -o ${K};; rm) sed -i -E "\#^${2:-${PWD}}\$#d" ${K};; ls) cat ${K};; *) cd "$(grep -e "$1" ${K} | head -n 1)";; esac fi }
Работает так: перейдя в какую-то часто посещаемую директорию, например, /usr/ports, пишем в командной строке k
для занесения ее в список часто посещаемых. В дальнейшем, ввод краткого k por
или даже k po
переносит нас в /usr/ports, что весьма удобно. k ls
покажет список всех сохраненных популярных мест, k rm
удалит текущее расположение из списка, k clean
отсортирует и дедублицирует список для пущей скорости поиска.
Резюмирую: ksh с вышеперечисленными плюшками более чем полностью покрывает все мои потребности в интерактивности и удобстве на текущий момент. Переезжать на zsh, tcsh, fish, bash и тому подобное - не вижу никакой необходимости, мой дефолтный ksh резв и удобен до безобразия.
text/gemini;
This content has been proxied by September (3851b).