Сегодня мы рассмотрим процесс конфигурации популярной командной оболочки ZSH⚙️ через файл загрузки окружения .zshrc📝 при использовании фреймворка oh-my-zsh.
🖐️Эй!
Подписывайтесь на наш телеграм @r4ven_me📱, чтобы не пропустить новые публикации на сайте😉. А если есть вопросы или желание пообщаться по тематике — заглядывайте в Вороний чат @r4ven_me_chat🧐.

Демонстрация, приведенная в данной статье выполнялась в среде дистрибутива Linux Mint 22🌱 (Ubuntu 24🦍). Аналогичным образом все будет работать и в других популярных дистрибутивах Linux☝️.
Погнали🏎.
TLDR
# установка необходимых утилит
sudo apt update && sudo apt install -y git curl zsh
# для "красочного" терминала установка bat, exa и grc
sudo apt install -y bat exa fzf grc || sudo apt install -y bat eza fzf grc
# бэкап существующего .zshrc
[[ -f ~/.zshrc ]] && mv -v ~/.zshrc{,_backup}
# скачивание готового .zshrc
curl -fsSL --output ~/.zshrc \
https://raw.githubusercontent.com/r4ven-me/zshrc/main/.zshrc
# смена оболочки по умолчанию
[[ $SHELL == *zsh ]] || chsh -s /usr/bin/zsh
# применение изменений для текущей сессии
exec zshПредисловие
Если вы много времени проводите в консоли/терминале Linux🧑💻, то вероятно, слышали про инструменты, которые облегчают взаимодействие с командной строкой и выводят «юзер экспириенс» на «новый уровень»🤔. Один из таких инструментов — оболочка ZSH и созданный умельцами фреймворк для ее простого и удобного конфигурирования — oh-my-zsh🔥.
Ранее я достаточно много времени потратил на приведение используемой мной оболочки к «идеальному», на мой взгляд или близко к тому состоянию🫠.
Ниже я приведу подробное описание своего конфига ZSH в файле .zshrc✍️, чтобы вы понимали, зачем вам это нужно.
После покажу (до безобразия простой🤷♂️) способ установки и применения данного конфига. Все внешние зависимости, такие как сам oh-my-zsh и дополнительные плагины, будут установлены автоматически🦾 при первом запуске ZSH.
💡 Процесс ручной установки ZSH + oh-my-zsh описан в отдельной статье.
Описание конфигурации .zshrc
В этом разделе представлено разделенное по блокам🧱 файла .zshrc описание того, что данный конфиг изменяет/дополняет в поведении оболочки ZSH.
ОБЩИЕ НАСТРОЙКИ🛠
- Добавление пользовательских директорий
bin,.bin,.local/binв переменнуюPATHдля упрощения доступа к пользовательским скриптам; - установка переменных окружения для работы с
oh-my-zsh(ZSH,ZSH_CUSTOM) и корректной поддержки цвета в терминале (TERM); - выбор темы оболочки в зависимости от среды:
agnoster-r4ven— для GUI и псевдотерминальных сеансов (PTS);dpoggi(без иконок) — для консольных сеансов (TTY);
- отключение автоматического обновления
oh-my-zsh(команда для обновления вручную:omz update); - настройка истории команд:
- хранение до 10,000 команд;
- добавление временных меток в формате
yyyy-mm-dd; - игнорирование повторяющихся записей и команд, начинающихся с пробела;
- общая история между терминальными сессиями🔥.
ПЛАГИНЫ🗃
Для улучшения работы с оболочкой используются следующие плагины:
fzf— поиск по истории команд с использованием утилитыfzf --exactчерезCtrl+r;git— алиасы и утилиты для работы с Git;sudo— быстрое выполнение последней/текущей команды с sudo через двойное нажатиеEsc;docker,kubectl— вспомогательные команды для Docker и Kubernetes;cmdtime— измерение времени выполнения команд (выводится в конце последней строки);zsh-autopair— автоматическое закрытие скобок и кавычек во время ввода команды;zsh-completions— расширенные автодополнения черезTabв т. ч. подкоманд и ключей команд;zsh-autosuggestions— подсвечиваемые подсказки на основе истории команд;fast-syntax-highlighting— подсветка синтаксиса команд;history-substring-search— поиск по истории при вводе части команды через стрелкивверх/вниз.
Несколько примеров использования:
Ctrl+r— вызовfzfдля поиска команды из истории;- при вводе части команды нажмите
Tabдля расширенного автодополнения (подкоманды, имена файлов или опции команд); - при вводе части команды нажмите
вверх, чтобы найти похожие команды из истории.
ПРИЛОЖЕНИЯ И УТИЛИТЫ🧑💻
- Установлены алиасы для упрощения часто используемых команд:
python->python3;- быстрый пинг DNS сервера Google по команде
p8, подсветка вывода командыip; - выбор редактора по умолчанию (
nvimилиvim) + удобные алиасы;
- установка цветовой палитры
Nordдля утилитыfzf; - использование
bat/batcat, как заменыcat,less,man,--helpиtail -fс подсветкой цветов темыNord; - замена команды
lsнаexa/ezaс улучшенными опциями отображения (длинный список, древовидный вывод, сортировка).
Подробнее про bat и exa смотрите в статье: bat, exa – подсветка синтаксиса стандартного вывода в терминале Linux (cat, less, tail и ls).
АВТОМАТИЧЕСКАЯ УСТАНОВКА🦾
При запуске оболочки она автоматически проверяет и устанавливает oh-my-zsh и недостающие плагины (zsh-autopair, zsh-completions, zsh-autosuggestions, fast-syntax-highlighting).
ФУНКЦИЯ БЫСТРОГО ВЫЗОВА КАСТОМНЫХ КОМАНД — cmd
Что делает функция:
- содержит массив из коротких ключей-имен команд, в значении которых расположены, нередко зубодробительные, команды;
- выводит весь список доступных команд с помощью ключа
-h; - умеет в интерактивность с помощью пролистывания вариантов с помощью клавиши
Tab; - после нажатия Enter команда не выполняется, а вводится в качестве следующей команды, но без выполнения, чтобы ее можно было отредактировать при необходимости.
Как выглядит работа такой команды/функции:

Вам остается лишь наполнить массив cmd_list своими командами, в формате:
short_name "long_command"Чувствительные для оболочки спец. символы, используемые в сложных командах — нужно экранировать. В каких-то случаях с помощью кавычек, в иных с помощью обратной косой чертой. Пример:
\$
ПРИГЛАШЕНИЕ ОБОЛОЧКИ👋
Убрано отображение user@host из приглашения оболочки, если используется графическая среда.
Демо моей конфигурации
Tab

Ctrl+r
history
--help
cat
less
tail
tailf
ls
ss
ping
journalctl
docker
Удобный доступ к кастомным сложным командам через универсальную функцию cmd:
И многое другое. Теперь переходим к подготовке и установке.
Подготовка
Установка необходимых пакетов
Предварительно нам необходимо установить саму оболочку zsh, утилиту для взаимодействия с веб curl и систему контроля версий git:
sudo apt update && sudo apt install -y git curl zshТакже (опционально) рекомендую установить утилиты для подсветки терминального вывода и удобного поиска:
sudo apt install -y bat exa fzf grc || sudo apt install -y bat eza fzf grcУстановка powerline шрифта для GUI сеанса
Для корректной отрисовки иконок в вашем терминале во время графической сессии — необходимо использовать специальный моноширный иконочный powerline шрифт🤯, например, из проекта Nerd fonts.
Мои читатели знают, что я предпочитаю шрифт Hack ☝️. Вот простой пример, как его можно установить:
📝 Примечание
Обратите вниманием, что для выполнения команд потребуются права sudo. Либо установите шрифты только для текущего пользователя в директории ~/.local/share/fonts.
# создаем директорию шрифта
sudo mkdir /usr/share/fonts/Hack
# скачиваем архив со шрифтами
curl -fsSLO \
$(curl -s https://api.github.com/repos/ryanoasis/nerd-fonts/releases/latest \
| grep browser_download_url \
| grep 'Hack.zip' \
| cut -d '"' -f 4)
# распаковываем архив, коприруем шрифты в систем
sudo unzip ./Hack.zip -d /usr/share/fonts/Hack/ && rm -f ./Hack.zip📝 Примечание
В команде curl используется механизм подстановки командной строки. Т.е. основной команде на скачивание: curl -fsSLO передается аргумент, который является результатом выполнения другой команды внутри конструкции $(command), выполняющейся предварительно. В итоге основная команда получит прямой URL на zip файл последнего релиза шрифта Hack из GitHub. Команда универсальна.

После установки шрифта, активируйте его в настройках вашего терминала🛠.
В Gnome-terminal это делается так:

Применение конфигурации .zshrc
Бэкапим текущий .zshrc, если он существует:
# бэкап текущего .zshrc
[[ -f ~/.zshrc ]] && mv -v ~/.zshrc{,_backup}Создаём новый .zshrc в любом удобном редакторе:
vim ~/.zshrcИ наполняем:
#======================================================
# Описание: Конфигурация .zshrc для oh-my-zsh
# Автор: Ivan Cherniy
# Основной сайт: https://r4ven.me
# Заметка о конфигурации: https://r4ven.me/zshrc-config
#======================================================
#============================================
# ОБЩИЕ НАСТРОЙКИ
#============================================
# Добавляем пользовательские директории в переменную PATH
if [[ -d "$HOME/bin" ]]; then PATH="$HOME/bin:$PATH"; fi
if [[ -d "$HOME/.bin" ]]; then PATH="$HOME/.bin:$PATH"; fi
if [[ -d "$HOME/.local/bin" ]]; then PATH="$HOME/.local/bin:$PATH"; fi
export PATH
export ZSH="$HOME/.config/oh-my-zsh" # Путь к установке Oh My Zsh
export ZSH_CUSTOM="$ZSH/custom" # Путь к пользовательской директории Oh My Zsh
export TERM="xterm-256color" # Устанавливаем тип терминала для лучшей поддержки цветов
# export TERM="screen-256color" # Альтернативный тип терминала (закомментировано)
have() {
local utils=("$@")
for util in "${utils[@]}"; do
if ! command -v "$util" &> /dev/null; then return 1; fi
done
return 0
}
cmd_alias() {
local cmd="$1"
shift
local replacement=( "$@" )
if alias "$cmd" &> /dev/null; then unalias "$cmd"; fi
if functions "$cmd" &> /dev/null; then unset -f "$cmd"; fi
eval "$cmd() { command ${replacement[@]} \"\$@\"; }"
}
# Автоматическая установка фреймворка oh-my-zsh
if [[ ! -d "$ZSH" ]] && have "git"; then
git clone https://github.com/ohmyzsh/ohmyzsh.git "$ZSH"
fi
# Выбор темы Oh-my-zsh
# Больше тем можно найти здесь: https://github.com/ohmyzsh/ohmyzsh/wiki/Themes
if [[ -n "$DISPLAY" || $(tty) == /dev/pts* ]] && have "curl"; then
R4VEN_THEME="agnoster-r4ven.zsh-theme"
if [[ ! -f "${ZSH_CUSTOM}/themes/${R4VEN_THEME}" ]]; then
curl \
--fail \
--location \
--show-error \
--output "${ZSH_CUSTOM}"/themes/"${R4VEN_THEME}" \
https://raw.githubusercontent.com/r4ven-me/zshrc/main/"${R4VEN_THEME}"
fi
# DASHES_COLOR=004
DASHES_COLOR="blue"
TIMER_FORMAT="%d"
TIMER_THRESHOLD=0
ZSH_THEME="${R4VEN_THEME%%.*}" # Используем эту тему в графическом режиме
export VIRTUAL_ENV_DISABLE_PROMPT=1 # Отключаем стандартный промпт virtualenv
else
ZSH_THEME="dpoggi" # Используем тему 'noicon' в других случаях, например, в консоли (tty)
fi
# Тема Powerlevel10k (требуется установка)
# https://github.com/romkatv/powerlevel10k
# ZSH_THEME="powerlevel10k/powerlevel10k"
DISABLE_AUTO_UPDATE="true" # Отключаем автоматические обновления для Oh My Zsh (команда: omz update)
COMPLETION_WAITING_DOTS="true" # Показывать точки при автодополнении команд
# Конфигурация истории команд
HIST_STAMPS="yyyy-mm-dd" # Добавлять метку времени к истории команд
HISTFILE=~/.zsh_history # Файл для сохранения истории
HISTSIZE=10000 # Максимальное количество записей в истории в памяти
SAVEHIST=10000 # Максимальное количество записей истории для сохранения в файл
setopt hist_ignore_all_dups # Игнорировать дублирующиеся записи в истории
setopt share_history # Делиться историей между сессиями
setopt histignorespace # Игнорировать команды, начинающиеся с пробела
# Включить режим vi для командной строки (по умолчанию - режим emacs)
# set -o vi
#============================================
# ПЛАГИНЫ
#============================================
plugins=(
fzf # Интеграция с Fuzzy finder (Ctrl+r)
git # Алиасы и функции Git
sudo # Запуск/повтор последней команды с sudo (двойной Esc)
docker # Помощник командной строки Docker
kubectl # Помощник командной строки Kubernetes
# zsh-autopair # Автоматическое закрытие скобок и кавычек
zsh-completions # Дополнительные скрипты автодополнения (Tab)
zsh-autosuggestions # Предложения команд на основе истории
fast-syntax-highlighting # Подсветка синтаксиса для команд
history-substring-search # Поиск в истории по подстроке (стрелки вверх/вниз)
)
# zsh-autopair: отключить этот плагин в MidnightCommander
# if ! [[ $(ps -o comm -h $PPID) =~ "^mc" ]]; then
# plugins+=(zsh-autopair)
# fi
# Автоматическая установка выбранных плагинов
if [[ -d "$ZSH_CUSTOM" ]] && have "git"; then
if [[ ! -d "${ZSH_CUSTOM}"/plugins/zsh-autopair ]]; then
git clone https://github.com/hlissner/zsh-autopair \
"${ZSH_CUSTOM}"/plugins/zsh-autopair
fi
if [[ ! -d "${ZSH_CUSTOM}"/plugins/zsh-completions ]]; then
git clone https://github.com/zsh-users/zsh-completions \
"${ZSH_CUSTOM}"/plugins/zsh-completions
fi
if [[ ! -d "${ZSH_CUSTOM}"/plugins/zsh-autosuggestions ]]; then
git clone https://github.com/zsh-users/zsh-autosuggestions \
"${ZSH_CUSTOM}"/plugins/zsh-autosuggestions
fi
if [[ ! -d "${ZSH_CUSTOM}"/plugins/fast-syntax-highlighting ]]; then
git clone https://github.com/zdharma-continuum/fast-syntax-highlighting \
"${ZSH_CUSTOM}"/plugins/fast-syntax-highlighting
reset
fi
fi
#============================================
# ИНИЦИАЛИЗАЦИЯ OH-MY-ZSH
#============================================
source "${ZSH}"/oh-my-zsh.sh # Инициализация фреймворка Oh My Zsh
autoload -Uz compinit && compinit # Инициализация и включение системы автодополнения
if [[ -r "${HOME}"/.profile ]]; then
source "${HOME}"/.profile # Загрузить '.profile', если он существует
fi
#============================================
# ПРИЛОЖЕНИЯ И УТИЛИТЫ
#============================================
# Python
cmd_alias "python" "python3"
# Сеть
cmd_alias "p8" "ping" "-c3" "8.8.8.8"
cmd_alias "ip" "ip" "--color"
# Настройка текстового редактора
if have "nvim"; then
export EDITOR="$(command -v nvim)"
export VISUAL="$(command -v nvim)"
alias vim="nvim"
alias n="nvim"
alias N="sudo nvim"
elif have "vim"; then
export EDITOR="$(command -v vim)"
export VISUAL="$(command -v vim)"
alias v="vim"
alias V="sudo vim"
fi
# Настройка FZF с цветами темы Nord
if have "fzf"; then
export FZF_DEFAULT_OPTS="--exact"
export FZF_DEFAULT_OPTS=$FZF_DEFAULT_OPTS'
--color=fg:#e5e9f0,bg:#2e3440,hl:#81a1c1
--color=fg+:#e5e9f0,bg+:#2e3440,hl+:#81a1c1
--color=info:#eacb8a,prompt:#bf6069,pointer:#b48dac
--color=marker:#a3be8b,spinner:#b48dac,header:#a3be8b
--color=border:#5e81ac
--border=rounded
'
fi
# Определение переменной с именем утилиты: bat или batcat
if have "batcat"; then bat="batcat"; else bat="bat" fi
# Использование bat вместо cat, less, man, --help, tail -f
# Подробнее: https://r4ven.me/bat-exa-config
if have "$bat"; then
export COLORTERM="truecolor"
export BAT_THEME="Nord"
export MANPAGER="sh -c 'col -bx | "$bat" --language=man --style=plain'" # Команда для просмотра man-страниц
export MANROFFOPT="-c" # Отключение переноса строк в man
cmd_alias "cat" "$bat" "--style=plain" "--paging=never"
cmd_alias "less" "$bat" "--paging=always"
if [[ $SHELL == *zsh ]]; then # глобальный алиас "--help" если zsh
alias -g -- --help='--help 2>&1 | "$bat" --language=help --style=plain'
fi
help() { "$@" --help 2>&1 | "$bat" --language=help --style=plain; }
tailf() { tail -f "$@" | "$bat" --paging=never --language=log; }
batdiff() { git diff --name-only --relative --diff-filter=d | xargs "$bat" --diff; }
fi
# Использование exa вместо ls
# Подробнее: https://r4ven.me/bat-exa-config
if have "exa"; then
if [[ -n "$DISPLAY" || $(tty) == /dev/pts* ]]; then # отображать иконки, если псевдотерминал
cmd_alias "ls" "exa" "--group" "--header" "--icons" "--time-style=long-iso"
else
cmd_alias "ls" "exa" "--group" "--header" "--time-style=long-iso"
fi
alias l="ls"
alias ll="ls --long"
alias lll="ls --long --all"
alias llll="ls -lbHigUmuSa --sort=modified --time-style=long-iso"
alias lm="ls --long --all --sort=modified"
alias lt="ls --tree"
alias lr="ls --recurse"
alias lg="ls --long --git --sort=modified"
fi
# Подсветка вывода различных команд
if have "grc" && tty -s && [[ -n "$TERM" && "$TERM" != dumb ]]; then
GRC_UTILS=(
configure ping traceroute gcc make netstat stat ss diff
wdiff last who cvs mount findmnt mtr ps dig ifconfig
df du env systemctl iptables lspci lsblk lsof blkid
id iostat sar fdisk free docker journalctl kubectl
sensors sysctl tail head tcpdump tune2fs lsmod lsattr
semanage getsebool ulimit vmstat dnf nmap uptime w
getfacl ntpdate showmount apache iwconfig lolcat whois
go sockstat
#ls ip
)
for cmd in "${GRC_UTILS[@]}"; do
if have "$cmd"; then
cmd_alias "$cmd" "grc" "--stderr" "--stdout" "$cmd"
fi
done
fi
# APT
if have "apt"; then
alias AU="sudo apt update"
alias AUP="sudo apt upgrade"
alias AR="sudo apt autoremove"
alias AI="sudo apt install"
alias AUI="sudo apt update && sudo apt install"
fi
# Ansible
if have "ansible"; then
AP() { ansible-playbook ~/ansible/playbooks/"$@"; }
alias AC="ansible-console"
fi
# Tmux
if have "tmux"; then
alias T="tmux attach -t Work || tmux new -s Work"
alias TT="sudo tmux attach -t Work! || sudo tmux new -s Work!"
fi
# ShellGPT
if have "sgpt"; then
export LITELLM_LOG="ERROR"
G() { sgpt --chat temp "$*"; }
GS() { sgpt --shell "$*"; }
GC() {
echo ""
sgpt --code --no-md "$*" | "$bat" --language=sh --paging=never --style=plain
echo ""
}
alias GG="sgpt --repl temp"
fi
# Определяет функцию 'cmd', которая выполняет пользовательские команды из списка
# Она принимает один аргумент - имя команды и вставляет её в командную строку
# Используйте клавишу TAB для подсказки
cmd() {
local cmd_name="${1}"
typeset -A cmd_list
# Ассоциативный массив для хранения списка команд
# Ключи — это имена команд, значения — сами команды
cmd_list=(
ps_top5_cpu "ps --sort=-%cpu -eo user,pid,ppid,state,comm | head -n6"
ps_top5_mem "ps --sort=-%mem -eo user,pid,ppid,state,comm | head -n6"
ps_zombie "ps -eo user,pid,ppid,state,comm | awk '\$4=="Z" {print \$3}'"
cron_add_task '{ crontab -l; echo "0 3 * * 0 ls -l &> dirs.txt"; } | crontab -'
du_top20 'du -x -h / 2> /dev/null | sort -rh | head -n 20'
df_80 "df -h | awk '\$5 ~ /^8[0-9]%/ {print $6}'"
git_init 'git init --initial-branch=main && git remote add origin ssh://git@github.com/r4ven-me/reponame.git'
journal_vacuum 'journalctl --vacuum-size=800M'
lsof_opened 'lsof +D /opt'
)
# Проверяем, существует ли команда в массиве, или если запрошена помощь
if [[ -z ${cmd_list[$cmd_name]} || -z "$cmd_name" || "$cmd_name" == "-h" ]]; then
# Отображаем список доступных команд
echo "ДОСТУПНЫЕ КОМАНДЫ:\n"
printf "%-20s %s\n" "Ключ" "Команда"
echo "----------------------------"
# Перебираем все ключи в массиве и отображаем их
for key in "${(@k)cmd_list}"; do
printf "%-20s %s\n" "$key" "${cmd_list[$key]}"
# echo "------------------"
done | sort
return 0
else
# Если команда найдена, вставляем её в командную строку
print -zr "${cmd_list[$cmd_name]}"
return 0
fi
}
# Функция для автодополнения команды
_cmd_completion() {
local -a keys
keys=($(cmd -h | awk 'NR>4 {print $1}')) # Извлекаем ключи из вывода справки
compadd "$@" -- "${keys[@]}"
}
# Регистрируем функцию автодополнения для команды `cmd`
compdef _cmd_completion cmd
#============================================
# ПРОМПТ
#============================================
# Удаляем контекст user@host из промпта, когда установлен DISPLAY
if [[ -n "$DISPLAY" && -z "$SSH_CONNECTION" ]]; then
prompt_context() { } # Пустая функция для отключения контекста
fi💡 Актуальная версия конфига всегда доступна на GitHub:
Закрываем/сохраняем и запускаем zsh в текущем сеансе:
exec zshexec- заменяет текущий процесс оболочки (в данном случае саму оболочку) на указанную команду, т.е.zsh;
Начнётся процесс скачивания недостающих компонентов в директорию ~/.config/oh-my-zsh:

Если вы в графическом сеансе, у вас будет минималистичный prompt:

В ином случае он будет таким:

Консольный же сеанс будет с использованием темы без иконок:

На данный момент мы просто запустили оболочку zsh в текущем сеансе☝️. Чтобы сделать zsh вашей оболочкой по умолчанию (если это не так) выполните команду:
[[ $SHELL == *zsh ]] || chsh -s /usr/bin/zshОписание команды
[[ ... ]]- проверяет условие внутри;$SHELL- переменная окружения, содержащая путь к текущей оболочке (например,/bin/bashили/usr/bin/zsh);== *zsh- проверяет, заканчивается ли значение переменной$SHELLнаzsh;||- выполняет следующую команду только если предыдущая вернула ложь (код возврата не равен 0);chsh- команда для изменения оболочки пользователя;-s /usr/bin/zsh- устанавливает Zsh как оболочку по умолчанию для текущего пользователя.
Готово. Для корректного применения изменений рекомендуется выйти из текущего сеанса и зайти заново🚶➡️.
Послесловие
В этот раз мы детально рассмотрели, как настроить поведение оболочки ZSH в файле .zshrc при использовании популярного фреймворка oh-my-zsh😌.
На мой взгляд, кастомизация своего рабочего пространства (в т.ч. оболочки) значительно увеличивает эффективность🧑💻. Если, конечно, не заниматься этим фанатично😉. Многие игнорируют данный момент, предпочитая дефолтные настройки. Не могу сказать, что это плохо, просто, имея некоторый опыт уяснил для себя: лучше потратить немного (или много) времени на настройку👨🔧 и просто пользоваться полученным конфигом везде, где возможно, тем самым решая различные задачи с большим удобством и меньшим количеством нервов😎.
Например, при вводе команды в терминале постоянно забываешь (или не знаешь🤷♂️), какие ключи у нее есть и что они делают. Приходится прерывать ввод, чтобы посмотреть справку. В случае моей конфигурации для большинства популярных команд достаточно просто нажать Tab, чтобы увидеть подсказку по ключам, которые еще и можно «протабать»👌. Сюда же относится удобство работы с историей команд и так далее😏.


