Переход с bash на zsh

  • Tutorial

Чтобы перейти с bash на zsh необходимо знать базовые отличия между ними — без этого будет сложно провести первоначальную настройку zsh в ~/.zshrc.


Я не нашёл краткого описания этих отличий когда переходил сам, и мне пришлось потратить немало времени на вычитывание документации zsh. Надеюсь, эта статья упростит вам переход на zsh.


Зачем переходить


Для начала — а стоит ли вообще тратить своё время и внимание на переход? Учить ещё один диалект sh, менее распространённый чем POSIX sh или bash, заново заниматься настройкой рабочего окружения…


На мой взгляд, если вы проводите много времени в консоли, вам нравятся Vim или Emacs и вы уже потратили немало времени на их настройку "под себя" — однозначно стоит! Zsh по духу очень на них похожа: это очень сложная и гибкая программа, чьи возможности полностью мало кто знает, но потратив некоторое время на настройку можно получить очень удобную лично вам рабочую среду.


Что касается изучения нового диалекта sh… пользы от этого, скорее всего, действительно мало, но описанного в этой статье минимума должно быть достаточно чтобы настраивать zsh, а писать новые скрипты на диалекте zsh вам никто и не предлагает. В общем и целом это ничем не отличается от необходимости минимально знать VimL или Emacs Lisp исключительно для настройки Vim/Emacs.


В инете куча статей и презентаций описывающих конкретные фичи zsh, значительно упростившие чью-то жизнь. Я не буду их перечислять, потому что фичи всем нужны разные, и в zsh найдутся варианты на любой вкус. Вместо этого я опишу ключевые особенности zsh, которые позволили реализовать эти фичи:


  • Zsh не использует readline для ввода команд пользователем. Вместо этого используется собственный редактор ZLE (Zsh Line Editor). Это позволило реализовать множество фич: удобное редактирование многострочных команд, подсветку синтаксиса прямо в процессе ввода команды, особую обработку "paste" из clipboard чтобы не выполнить случайно вставленный текст, гибкое управление горячими клавишами, undo (в т.ч. отменяющее результат автодополнения и разворачивания glob-ов)… плюс интегрировать функционал редактора с zsh, что позволяет управлять его поведением через обычные функции zsh (например, подсветка синтаксиса так и реализована).
  • Невероятно сложный и гибкий механизм автодополнения команд. Он сильно зависит от контекста, поэтому при нажатии <Tab> в разных местах командной строки будут дополняться разные вещи: имена команд, их параметры, файлы, имена пользователей и серверов, номера процессов, названия переменных, индексы массивов и ключи хешей, элементы синтаксиса zsh, названия цветов и шрифтов, сетевых интерфейсов, системных пакетов… короче, вообще всего что можно автодополнять. И его можно детально контролировать, вплоть до изменения логики автодополнения для конкретного контекста у конкретной команды.
  • Громадное количество (177 в zsh-5.2) опций, изменяющих поведение zsh. С их помощью можно, например, изменять поддерживаемый синтаксис и включать (в т.ч. частично) режимы совместимости с sh/bash/ksh/csh. Они позволяют настолько значительно влиять на работу, что в zsh пришлось сделать отдельный "режим совместимости с zsh", который многие функции обычно включают первой командой, потому что только это даёт им гарантию, что код этой функции будет понят zsh именно так, как ожидал его автор.
  • Предпочтение максимально сжатого, краткого синтаксиса — чтобы вам нужно было набирать как можно меньше текста для выполнения типичных, пусть даже довольно сложных, задач. В коде, где важна читабельность через месяц — это однозначно минус. Но в командной строке — однозначно плюс.
  • Модульная организация настроек через фреймворки (вроде oh-my-zsh и prezto), плагины, темы, etc. На самом деле здесь нет ничего специфичного для zsh, ровно то же самое можно сделать и для bash, но… почему-то для zsh всё это уже есть, а для bash — нет (а если и есть, то про это мало кто знает). А это даёт возможность относительно быстро собрать свой вариант настроек zsh из готовых "кубиков" (как пример, посмотрите видео менеджера плагинов zsh Аntigen), точно так же, как обвешивается плагинами Vim.

Отличия и совместимость


Ещё раз уточню, что я буду описывать именно отличия от bash, а не полный набор возможностей zsh. Большая часть привычного вам функционала работает в zsh точно так же, как и в bash. Но при этом часто есть специфичные для zsh способы делать примерно то же самое. Это связано с тем, что в zsh уделяется очень много внимания совместимости с другими шеллами, поэтому в zsh плюс к своим фичам перетащили очень многое из других шеллов — и в результате получили несколько альтернативных способов делать одно и то же.


Термины


  • Параметр: обычная переменная — скаляр (строка, целое, дробное), массив, ассоциативный массив (хеш). А переменными называют в основном переменные окружения, т.е. экспортированные скалярные параметры.
  • Аргумент: параметр (в традиционном смысле) вызываемой команды или функции (аргументы функции доступны через параметры $@, $1, …).
  • Шаблон: глоб. Как правило шаблоны подразумевают совпадение с реально существующими файлами, но в некоторых случаях они применяются к строке или значению параметра. Поддержка полноценных регулярок тоже есть, но в основном везде в качестве шаблонов для совпадения или поиска/замены используются глобы.
  • Флаги: задаются в круглых скобках перед тем, на что они должны влиять. Для параметров задаются между открывающей фигурной скобкой и именем параметра: ${(kv@)some_hash}. Для шаблонов могут быть в начале или середине: *CaseImportant(#i)CaseIgnored*.txt.
  • Квалификаторы: задаются в круглых скобках после шаблона, уточняя его свойствами не связанными с именем файла: *(/^F).
  • Модификаторы: задаются каждый после двоеточия, применяются по очереди изменяя текущее значение. Для параметров задаются после имени параметра: $PWD:h:t, ${some_param:h:t}. Для шаблонов задаются перед закрывающей круглой скобкой квалификаторов: *(:e).

Текущие настройки


Многие встроенные команды выводят текущее состояние при запуске без аргументов (плюс нередко у них есть аргумент, который оформляет вывод в стиле команд zsh, что довольно удобно).


# текущие опции
setopt
# полный список всех опций
setopt KSH_OPTION_PRINT; setopt

# список обрабатываемых кнопок в текущем режиме
bindkey
# список обрабатываемых кнопок во всех режимах, в формате команд zsh
for m in $(bindkey -l); bindkey -M $m -L

# текущие стили (контекстно-зависимые настройки)
zstyle
zstyle -L

# текущие алиасы (обычные плюс глобальные), в формате команд zsh
alias -L
# текущие алиасы для суффиксов, в формате команд zsh
alias -s -L

# текущие параметры (переменные)
typeset
# текущие параметры (переменные), в формате команд zsh
typeset -p

Это далеко не полный список, но для большинства задач в процессе (анализа) настройки zsh его должно хватить.


Ещё может быть полезным запуск zsh -f — это запускает zsh в состоянии по умолчанию (без выполнения любых стартовых скриптов кроме /etc/zshenv, которого в большинстве систем и так нет).


setopt и emulate


  • В именах опций регистр и подчёркивания значения не имеют, плюс перед любой опцией можно добавить префикс "no".
  • Вызов для одной и той же опции setopt с префиксом "no" и unsetopt без "no" (равно как и наоборот!) делают одно и то же.
  • В выводе setopt используются маленькие буквы без подчёркиваний, в документации используются большие буквы с подчёркиваниями. Это создаёт некоторое неудобство — при поиске в документации нужно догадаться, где вставлять подчёркивания чтобы найти нужную опцию.
  • Команда emulate позволяет массово установить группу опций в состояние совместимости с sh, ksh, csh или в состояние по умолчанию для zsh. Многие функции в zsh начинаются командой emulate -L zsh, что позволяет на время выполнения функции привести ключевые опции в состояние по умолчанию для zsh — без этого большинство нетривиальных функций может ломаться из-за выставленных пользователем опций (например, есть опция которая управляет тем, как индексируются массивы — от 1 или от 0).

# все эти команды делают одно и то же
setopt nonumericglobsort
setopt NO_numericglobsort
setopt NO_NUMERIC_GLOB_SORT
setopt _N_O_numERICglob_SORT_
unsetopt NUMERIC_GLOB_SORT
unsetopt numericglobsort

В начале использования zsh, для более привычной работы после bash, я бы рекомендовал следующие опции:


# традиционный стиль перенаправлений fd
unsetopt MULTIOS
# поддержка ~… и file completion после = в аргументах
setopt MAGIC_EQUAL_SUBST
# не обрабатывать escape sequence в echo без -e
setopt BSD_ECHO
# поддержка комментариев в командной строке
setopt INTERACTIVE_COMMENTS
# поддержка $(cmd) в $PS1 etc.
setopt PROMPT_SUBST

Ещё есть опция SH_WORD_SPLIT, и формально для привычной работы после bash её тоже надо включить, но я бы этого не рекомендовал: поведение zsh без этой опции более удобное и логичное, лучше сразу к нему привыкать. Она отвечает за то, как сработает cmd $PARAM если значение $PARAM это строка содержащая пробелы: в bash cmd получит несколько аргументов, а в zsh — один (как если бы вызвали cmd "$PARAM"). А если $PARAM это массив, то zsh передаст cmd по одному аргументу на каждый не пустой элемент массива (даже если эти элементы содержат пробелы).


(В основном, эта статья описывает поведение zsh с опциями по умолчанию, иначе каждое второе предложение пришлось бы уточнять в стиле "но вот при таких-то опциях всё это работает иначе".)


Параметры


  • Соглашение: для имён скалярных параметров (строки, целые и дробные числа) обычно используют $БОЛЬШИЕ буквы, а для массивов (обычных и ассоциативных) — $маленькие.
  • Через typeset -U можно объявить массив с уникальными элементами (попытки добавления уже существующих элементов будут игнорироваться).
  • Через typeset -T можно связать массив со скаляром в формате $PATH. Несколько таких связанных параметров уже созданы: $PATH и $path, $FPATH и $fpath, $MANPATH и $manpath, $CDPATH и $cdpath. Для связанных параметров не имеет значения какой из них мы изменяем — изменяются сразу оба. Поэтому в zsh с такими параметрами практически всегда работают через массивы ($path, $fpath, …) — это значительно удобнее.
  • Некоторые скалярные параметры так же связаны между собой, например $PS1, $PROMPT и $prompt (хотя, это скорее просто синонимы для одного параметра).

Массивы


  • Индексируются с 1.
  • Можно использовать отрицательные индексы (от конца массива).
  • Можно использовать срезы.
  • При использовании как скаляра — объединяют элементы через пробел.
  • Индексирование скаляра возвращает символы строки.
  • Глоб возвращает массив, так что индекс можно использовать как квалификатор глоба: *([2,-2]).

Шаблоны


  • **/ — совпадает с подкаталогом любого уровня вложенности, включая отсутствие подкаталога
  • <число1-число2> — совпадает с числом в заданном диапазоне в имени файла, и начало и конец диапазона можно не указывать
  • (шаблон1|шаблон2) — альтернатива (так же — группирующие скобки при использовании опции EXTENDED_GLOB)
  • если включить опцию EXTENDED_GLOB, то в шаблонах можно будет дополнительно использовать # (повтор предыдущего элемента), ~ и ^ (исключение из совпадения)

# показать файлы в текущем каталоге или его подкаталогах,
# которые содержат в имени число большее или равное 5 либо строку example,
# и у которых расширение .txt
ls -l **/*(<5->|example)*.txt

Флаги/Квалификаторы/Модификаторы


Квалификаторы есть только у шаблонов, они позволяют задать дополнительные условия отбора файла: по типу (файл/каталог/симлинк/etc.), правам, времени (изменения/etc.), размеру… Можно сортировать и индексировать отобранные файлы. Можно включить для конкретно этого шаблона совпадение начальной * с именами начинающимися на точку. Можно включить удаление этого шаблона из аргументов командной строки если он не совпал ни с одним файлом.


# до 5-ти подкаталогов текущего каталога,
# имена которых могут начинаться на точку и содержат "a",
# которые изменялись последними
ls -ld *a*(D/om[1,5])

Если включить опцию EXTENDED_GLOB, то в шаблонах можно будет использовать флаги: для файлов интерес представляет управление чувствительностью к регистру, а при совпадении с параметром/строкой есть и другие полезные флаги.


# эти команды идентичны
ls -ld .[cC][oO][nN][fF][iI][gG]*
setopt extendedglob; ls -ld .(#i)Config*

Для параметров доступно намного больше флагов: вывод всех (включая пустые) элементов массива даже в кавычках, выполнение join или split по заданной подстроке, вывод только ключей и/или значений ассоциативного массива, экранирование разными видами кавычек и обратная операция, etc.


# вывод ключей ассоциативного массива вместо значений
echo ${(k)some_hash}
# преобразовать $PATH в массив разделив на элементы по ":",
# после чего корректно взять каждый элемент в одинарные кавычки
echo ${(s<:>qq)PATH}

И для шаблонов и для параметров можно использовать модификаторы: удаление последнего элемента пути, удаление всех элементов пути кроме последнего, удалить/оставить расширение, экранирование и обратная операция, поиск и замена подстроки, etc.


# вывод имени родительского каталога (сначала отбрасываем последний
# элемент пути, потом отбрасываем все элементы пути кроме последнего)
echo $PWD:h:t
# вывести имена (без каталога) всех симлинков в любом подкаталоге,
# заменив в них подстроку "fil" на "FIL" (если такая подстрока есть)
echo **/*(@:t:s/fil/FIL/)

autoload -Uz


Помимо традиционного способа подгружать код через source /path/to/file.sh или . /path/to/file.sh в zsh активно используется автозагрузка кода в момент первого вызова функции.


Для поиска файла с нужной функцией используется $FPATH — переменная аналогичная по формату $PATH, содержащая список каталогов в которых выполняется поиск файла с именем, идентичным имени загружаемой функции.


При вызове autoload никаких файлов с диска не считывается, и даже не проверяется их наличие — всё это произойдёт при первом вызове функции. Практически всегда необходимо передавать autoload аргументы -U (отменяет эффект текущих alias-ов для загружаемого файла, потому что нередко alias-ы настроенные пользователем могут нарушать работу сторонних функций) и -z (необязательное уточнение что загружаемый файл — в формате zsh, но безопаснее его всегда задавать).


fpath=(~/my-zsh-functions $fpath)
autoload -Uz fn
fn

При этом содержимое файла ~/my-zsh-functions/fn может быть в одном из этих трёх форматов:


# Просто набор команд, без каких-либо функций:
echo "Я функция fn"

# Одна функция с именем совпадающим с именем файла:
fn() {
    echo "Я функция fn"
}

# Набор из любых команд и функций, включая fn:
fn() {
    fn2
}
fn2() {
    echo "Я хелпер функции fn"
}
echo "Выполнится перед первым запуском fn"
# Но файл должен содержать явный вызов fn:
fn "$@"
echo "Выполнится после первого запуска fn"

zkbd


При первом запуске zsh нередко оказывается, что часть кнопок вроде F1/Backspace/Delete/курсора работает некорректно. Это связано с тем, что абсолютное большинство консольных приложений использует readline и корректная настройка этих кнопок считывается из /etc/inputrc и ~/.inputrc, а zsh этого не делает.


Проблема решается в лоб — нужно посмотреть, какие escape-последовательности выдают нужные кнопки в вашем терминале и задать в ~/.zshrc нужные обработчики для этих escape-последовательностей. Примерно так:


bindkey '^[[A' up-line-or-history       # Up
bindkey '^[[B' down-line-or-history     # Down
# и т.д.

Смотреть выдаваемые кнопками последовательности можно запустив cat >/dev/null и нажимая Ctrl-V перед нужной кнопкой. (И таки да, занимаясь этим в 2017 я чувствовал себя немного странно…) Но в комплекте с zsh идёт вспомогательная утилита zkbd, которая автоматизирует этот процесс. Для этого необходимо подключить её в ~/.zshrc, после чего у вас появится ассоциативный массив $key содержащий нужные escape-последовательности:


autoload -Uz zkbd
[[ ! -f ~/.zkbd/$TERM-${${DISPLAY:t}:-$VENDOR-$OSTYPE} ]] && zkbd
source  ~/.zkbd/$TERM-${${DISPLAY:t}:-$VENDOR-$OSTYPE}

[[ -n $key[Up]   ]] && bindkey -- $key[Up]   up-line-or-history
[[ -n $key[Down] ]] && bindkey -- $key[Down] down-line-or-history
# и т.д.

Я не уточняю детально какие команды (вроде up-line-or-history) на какие кнопки назначать потому, что во-первых назначать надо не все подряд, а только те, которые у вас из коробки не заработают, и во-вторых если мнения насчёт того, что должны делать Home или Backspace у всех сходятся, то вот поиск в истории по Up и Down может выполняться довольно разными способами, и функции в этих случаях на эти кнопки надо назначать тоже разные.


(Кстати, задавать символ Escape (^[) в параметре bindkey можно и настоящим символом, вводя его через Ctrl-V, и двумя обычными символами ^[, и двумя символами \e.)


zstyle


Это встроенный способ использовать контекстно-зависимые настройки. Он во многом похож на обычные параметры, только помимо имени и значения параметра zstyle позволяет задать шаблон "контекста". А потом получать значения относящиеся к текущему контексту. Этот подход активно используется для настройки работы автодополнений, но им можно пользоваться и для своих скриптов.


# установим значение my-param=default для 3-х уровневого контекста,
# где на первом уровне идентификатор нашего приложения (у всех
# приложений общая база zstyle, так что свои настройки надо изолировать)
# а на следующих двух уровнях любые значения
% zstyle ':my-app:*:*' my-param default
# установим значение my-param=val-one для контекста, у которого на
# втором (более приоритетном) уровне будет значение "one"
% zstyle ':my-app:one:*' my-param val-one
# установим значение my-param=val-two для контекста, у которого на
# третьем (менее приоритетном) уровне будет значение "two"
% zstyle ':my-app:*:two' my-param val-two

# получаем значение my-param в переменную result для заданного контекста
% zstyle -s ':my-app:a:b' my-param result
% echo $result
default
% zstyle -s ':my-app:one:b' my-param result
% echo $result
val-one
% zstyle -s ':my-app:a:two' my-param result
% echo $result
val-two
% zstyle -s ':my-app:one:two' my-param result
% echo $result
val-one

zmodload


Часть дополнительного функционала zsh реализована не в обычных скриптах подгружаемых через autoload -Uz, а как системные библиотеки *.so. Они используются, например, для предоставления доступа к регулярным выражениям PCRE, математическим функциям, сокетам, etc. Такие библиотеки подгружаются через zmodload.


Разное


Для перехвата сигналов помимо стандартного trap '…;code;…' INT можно использовать функции с особыми именами: TRAPINT() { …;code;… }.


У многих конструкций вроде if, while, etc. есть сокращённая форма (пример есть выше, где выводилось значение всех режимов bindkey).


Внезапно, zsh-специфичный аналог echo — команда print — оказалась весьма удобной при изучении zsh. Она много чего умеет, но из самого полезного:


# вывод по одному аргументу на строку, удобно для массивов
print -l $path
# вывод по два аргумента на строку в столбцах,
# удобно для ключей и значений ассоциативных массивов
print -a -C 2 "${(kv@)ZSH_HIGHLIGHT_STYLES}" | sort
# вывод используя %-последовательности используемые в $PS1
print -P '%Bbold%b %F{red}current%f dir is: %~'

Если Когда решитесь переходить на zsh, то для принятия конкретных решений про фреймворки/модули/темы вам пригодится Awesome-коллекция всего для zsh.

Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.

Использование zsh

  • 48.7%Уже использую zsh220
  • 11%Использую другой шелл, но подумываю о переходе на zsh50
  • 6.8%Использую другой шелл, не очень им доволен, но на zsh переходить не планирую31
  • 22.1%Использую другой шелл и полностью им доволен100
  • 8.4%Не использую шелл/использую слишком мало чтобы о нём задумываться38
  • 2.6%Использовал zsh, но перешёл на другой шелл12
Поделиться публикацией

Комментарии 115

    +1

    Перешел на zsh по одной причине: bash постоянно теряет историю. Вроде бы эта проблема давно уже «исправлена», но нет, все равно в какой-то момент история полностью сбрасывается. Почти никакими плюшками zsh не пользуюсь, ценю только за то, что помнит историю годами. Активный пользователь Meta-R. :)

      0
      А как там обстоит дело с историей из нескольких ssh терминальных сессий? В баше сохраняется только из одной, если верно помню.
        +5
        shopt -s histappend
        PROMPT_COMMAND='history -a'
        В ~/.bashrc говорят, что вы помните неправильно.
        В комментариях к каждой статья про zsh повторяется чушь про башхистори, типа вашей.
          –1
          Там у каждого терминала есть так сказать свой буфер который флашится на диск или при закрытии терминала и при выполнении соттв. команды.
          0
          прям вообще не сбрасывается?
          +2
          Давно перешёл на zsh, но использую всё так же, как раньше bash. Т.е. никакими фирменными фичами так и не пользуюсь. Установил только Oh My Zsh и выбрал шаблон по вкусу :)
          Ещё заметил, что bash всегда стартует почти мгновенно, а zsh с небольшой задержкой.
            +4
            Думаю это десятки плагинов Oh My Zsh у вас стартуют
              0
              Скорее всего.
              0

              Заметил, что задержка появилась после того, как поставил NVM. До этого сессия стартовала мгновенно.

                0
                У меня NVM тоже стоит, но заметил задержку ещё до установки NVM.
              +4
              При всем уважении к разработчикам, я отношусь к zsh как к куче батареек для bash, которыми до конца никто пользоваться не умеет. Батарейки известно к чему ведут — лишние тормоза, баги с совместимостью, неполноценная документация и, как следствие, отсутствие понимания происходящего. Кстати, я что-то не встречал ни одного системного администратора, использующего zsh вместо bash на постоянной основе в своей работе, а эти ребята хорошо разбираются в применении консольных инструментов и конкретно интерпретаторов именно по назначению.

              Ну и как водится, что только не придумают, чтобы bash/sh не изучать.

              P.S. в опрос неплохо бы добавить, использовал zsh, но перешел обратно на другой интерпретатор
                0
                P.S. в опрос неплохо бы добавить, использовал zsh, но перешел обратно на другой интерпретатор

                Да, мне тоже эта мысль недавно пришла в голову. Добавил.

                  0
                  > Кстати, я что-то не встречал ни одного системного администратора, использующего zsh вместо bash на постоянной основе в своей работе

                  А я встречал, почему-то
                    –1
                    Сколько промышленных серверов и какого типа (vm, dedicated, embedded) было у этих администраторов в эксплуатации?
                      +1
                      Я могу узнать, если Вам интересно. А что значит «промышленных»?
                        0
                        И ещё: Вас интересует одномоментная эксплуатация, или за всю историю?
                          0
                          Прошу прощения, я напутал. Был уверен, что zsh, а оказалось — какой-то форк ksh, да ещё и далеко не на всех серверах. Жаль, что нельзя теперь удалить своё сообщение. :(
                            +1
                            Вот и я говорю, что такого нет. Под пром серверами имею в виду production
                              0
                              Собственно в вашем вопросе — половина ответа. Zsh хорош, когда вы можете подстроить его под себя, а когда от половины до трех четвертей времени ты проводишь на серверах, где zsh просто нет и/или подстроить его под себя нельзя (например там один пользователь, из-под-которого работают 10 человек), то тебе приходится держать в голове и помнить — где у тебя что.

                              Оказывается, что жить всегда без удобств zsh проще, чем вот так — нараскоряку…
                                +1

                                Не понятно что имеется ввиду под применял? На боевых серверах? Врятли, хотя я такое видел на инфраструктуре одного крупного клиента. Там было машин 500. Админ редко один, поэтому нужно находить компромис с коллегами. А компромис этот либо bash, либо ksh (если надо держать совместимость со старым Unix, типа Чпукса)


                                А вот локально каждый развелкается как умеет. У меня это адовая смесь из bash и скриптов на perl, а у одного бывшего коллеги как раз zsh на все случаи жизни. И некоторые патерны из zsh мне нравятся. На столько нравятся, что я думаю все таки попробую в ближайшее время.


                                Например меня интересует подгрузка кода по контексту: в баш приходится либо вилосепедить, либо применять что-то на подобии https://github.com/cxreg/smartcd.git Также интересно выглядит отложенная подгрузка кода. Не уверен, что это даст большой буст, но на взгляд source ~/.bashrc_my у меня уже давно подтормаживает при том, что по большей части этот код имеет узкую специализацию и нужен редко или в определенном котексте (smartcd, кстати сильно спасает).

                                  0
                                  Админ редко один, поэтому нужно находить компромис с коллегами.

                                  Просто не надо использовать общие аккаунты и sudo -i. Если каждый админ использует личный аккаунт и sudo для индивидуальных команд — ему ничего не мешает иметь личный ~/.zshrc. Помимо прочего это намного более здраво в плане безопасности, аудита и контроля доступа отдельных сотрудников.

                                    0

                                    sudo -s может потребовать внимания с точки зрения правильного выставления ENV. Т.е. здесь вопрос сответствия затрат на унифицирование разнобразных .profile. Не все отделы на это пойдут.


                                    Плюс, есть один, очень важный момент в работе больших админских отделов. Так называемые "notes". Суть состоит в том, что админ дублирует команды в некоторый текстовый (или md), общедоступный файл, разумеется с пояснениями и комментариями. Файл этот каким-либо образом привязан к тикет системе. В следущий раз, если возникает необходимость сделать то же самое, его колега уже будет не в полной темноте. А в третий раз, уже начнется оптимизация: участки будут переписаны как скрипты для bash/zsh/ansible и т.п. В таком виде один шел на всех очень важен. Это средство обмена опытом, нахождение общих патернов и т.д.


                                    Вышеуказанное это реальный опыт организации работы в компании, которая занимается поддрежкой очень крупных и дорогих клиентов (я в ней начинал админскую карьюеру много лет назад).

                                      –1

                                      Особый общий ENV большинству команд не требуется, но в любом случае это не проблема — если он "общий", то какая разница, поддерживать его в /root/.bashrc или в /etc/profile.d/?
                                      Notes в виде файла на конкретном сервере? Вы так шутите? Ну или это было очень-очень много лет назад. Сейчас для этой цели есть wiki.
                                      Скрипты для bash/zsh/ansible — на то и скрипты, чтобы их можно было запускать всем, вне зависимости от того, какой у кого $SHELL.


                                      реальный опыт организации работы в компании, которая занимается поддрежкой очень крупных и дорогих клиентов

                                      Во-во. Типичные условия развития махрового консерватизма, когда всё делается по принципу "так было всегда" и "ничего не менять пока мы из-за этого не теряем деньги". К здравому смыслу и эффективной работе всё это отношения не имеет.

                                        0
                                        Сейчас для этой цели есть wiki.

                                        Без разницы в каком это виде, главное что б было, работало и поволяло вычленять общие патерны и не изобретать велосипеды.


                                        К здравому смыслу и эффективной работе всё это отношения не имеет.

                                        Категоричность обычно не является профессионализмом. Прочитайте ещё раз свой и мой текст, и поймете, что в общем-то наша позиция не отличается.

                                          0
                                          Категоричность обычно не является профессионализмом.

                                          Звучит немного категорично, нет? :)


                                          На самом деле категоричность с профессионализмом не связана вообще никак (не обязательно верить мне на слово, можете посмотреть определение терминов в словаре, например). Если ты очень хорошо владеешь каким-то инструментом или имеешь много опыта в какой-то области, то вполне можно позволить себе категоричные высказывания на этот счёт — почему нет, если ты действительно знаешь, о чём говоришь? Просто категоричные высказывания часто позволяют себе фанбои, которые недавно открыли для себя что-то классное, при этом толком не разбираются в том, о чём говорят, либо не учитывают, что ситуации бывают разные — отсюда и представление, что категоричность симптом непрофессионализма.


                                          А если заведется любитель fish или ipython или tcsh? :)

                                          Переменные окружения заданные в формате posix sh подчитать смогут все, так или иначе. Суть ведь не в том, чтобы сделать удобно всем сразу, а в том, чтобы дать возможность желающим сделать себе удобно самостоятельно.

                                            0
                                            Звучит немного категорично, нет? :)

                                            Рекурсия, но и клин-клином.


                                            Переменные окружения заданные в формате posix sh подчитать смогут все

                                            csh точно нет — это антогонисты. Остальными не пользовался.


                                            Суть ведь не в том, чтобы сделать удобно всем сразу, а в том, чтобы дать возможность желающим сделать себе удобно самостоятельно.

                                            Ну допустим. Есть практический опыт? Мне это кажется утопичным.

                                              0
                                              csh точно нет — это антогонисты. Остальными не пользовался.

                                              У fish тоже свой синтаксис с set. Только setenv не обязателен хотя и есть зачем‐то, можно использовать set -x.

                                                0

                                                Поэтому я и написал "… подчитать смогут все, так или иначе". Можно оставить основным шеллом bash или даже sh, просто написать в ~/.bashrc exec fish/tcsh, чтобы они запустились уже с этими переменными, можно загрузить в них эти переменные кучей других способов. Об этом не должна болеть голова при основном администрировании сервера, это вполне может быть личной проблемой тех, кому нужен fish/tcsh — главное, чтобы для них эта проблема была решаемой в принципе.

                                                +1

                                                Мой практический опыт сводится к тому, чтобы во-первых избегать использования общих админских аккаунтов, и во-вторых стараться на сервера вообще ручками ходить по-реже и делать там по-меньше, а не к тому, чтобы на любом из 1000 серверов было удобно работать в zsh через sudo (в этом плане, кстати, когда на серверах работать неудобно — это скорее плюс, лишний мотив этого избегать в принципе). Удобно работать должно быть на рабочей станции и на 2-3 уникальных серверах, которые админятся по-старинке ручками, а не через ансибл.


                                                Но мы вроде не мой личный практический опыт обсуждали, а принципиальную возможность и смысл установки zsh на сервера, причём по умолчанию, из коробки. На мой взгляд ничего утопичного в том, чтобы не использовать общий аккаунт для администрирования и в том, чтобы поставить везде пакет zsh — нет. Насколько это нужно реальным юзерам — посмотрите на результаты голосования, даже учитывая что статья про zsh они довольно показательны.

                                                  0

                                                  Общим аккаунтом в любом случае остается тот под которым запущено приложение. Этого не избежать. И переключаться под него через sudo приходится.


                                                  и во-вторых стараться на сервера вообще ручками ходить по-реже и делать там по-меньше

                                                  Ну в такой крутой инфраструктуре весь это вопрос не имет никакого значения.

                                                    0

                                                    Всё верно. :(


                                                    Теоретически, можно дать доступ ко всем нужным файлам приложения через права группы и setgid-каталоги, поставить всем umask 0002, тогда через sudo под аккаунтом самого приложения надо будет исключительно его запускать/перезапускать, а работать можно под личным аккаунтом.


                                                    Но при попытке применять этот подход на практике постоянно вылезали какие-то шероховатости. Нередко попадаются не очень качественно написанные приложения и скрипты, которые нечаянно удаляют setgid-бит каталогам когда пытаются изменить их права. Или, зачем-то, игнорируют umask и форсируют "безопасные" права. Плюс, имея полный доступ к файлам приложения его возможно запустить под личным аккаунтом, и очень часто по ошибке это и делали. А потом другой юзер не мог прибить процесс чтобы его перезапустить. Последнее, вероятно, проблема решаемая — можно в стартовом скрипте приложения проверять $UID, например, но количество излишних сложностей и потенциальных проблем начинает превышать комфортный уровень, в результате чего все на это забивают и продолжают пользоваться общим аккаунтом.

                                                      0

                                                      set[ug]id очень неприятная идея. Не зря в современных дистрибах уже почти не осталось подобных мест.

                                                        0

                                                        Для выполнимых файлов — безусловно. Но на каталоге setgid чем плох?

                                                          0

                                                          Сложно сказать. Вроде все довольно прозрачно, но как-то я не видел чтоб это широко использовалось.

                                            +2
                                            его в /root/.bashrc или в /etc/profile.d/

                                            А если заведется любитель fish или ipython или tcsh? :)

                            +1

                            Меня как сидящего все еще на bash интересует,
                            для начала две базовые вещи:


                            1. как сделать "бесконечную" историю? На bash я использую такой код:
                              export HISTCONTROL=ignoredups
                              export HISTFILESIZE=-1
                              export HISTSIZE=-1
                            2. Как поставить такой же "prompt" как у bash?
                              case ${TERM} in
                                  [aEkx]term*|rxvt*|gnome*|konsole*|interix)
                                          PS1='\[\033]0;\u@\h:\w\007\]'
                                          ;;
                                  screen*)
                                          PS1='\[\033k\u@\h:\w\033\\\]'
                                          ;;
                                  *)
                                          unset PS1
                                          ;;
                              esac
                              0

                              Я сходу не вижу в доке возможности указать -1 для HISTSIZE, но… а Вам реально важно, чтобы она была именно бесконечная? Учитывая что история считывается в память, что занимает время и место, значение HISTSIZE более 1 миллиона вряд ли имеет смысл (это даёт размер файла с историей порядка 50MB, и будет хранить историю примерно за 1 год).


                              Что касается PS1 — можно точно так же и поставить, разве что escape-последовательности будут другие. Но обычно в zsh для обновления заголовка терминала используют другой подход: существуют функции-хуки precmd и preexec, автоматически вызываемые перед выводом приглашения и перед запуском команды, и обновление заголовка терминала прописывают обычно в них (в частности, это даёт возможность записать в заголовок имя запущенной команды пока она выполняется, а не только текущий каталог). В oh-my-zsh это работает из коробки, в prezto не проверял, но скорее всего тоже.

                                +1
                                а Вам реально важно, чтобы она была именно бесконечная?

                                Да, да и еще раз да. Нафига мне задумываться о том сколько строчек оставить,
                                а если для меня будет важна именно 1_000_000 + 1?


                                Иногда очень нужно посмотреть: "а какой хитрой командой
                                я делал вещь X пять лет назад?" Можно конечно сохранять хитрые команды в файлы,
                                или иметь файл snipets, но смысл если bash умеет все это сам сохранять.


                                Учитывая что история считывается в память, что занимает время и место, значение HISTSIZE более 1 миллиона вряд ли имеет смысл (это даёт размер файла с историей порядка 50MB, и будет хранить историю примерно за 1 год).

                                bash не считывает всю историю в память, а только несколько последних X строк (проверенно экспериментально),
                                плюс более ignore dups делает свое дело:


                                $ ls -lh .bash_history 
                                -rw------- 1 evgeniy evgeniy 3,4M апр 15 22:19 .bash_history
                                $ wc -l .bash_history
                                117402 .bash_history

                                Этому ноутбуку года 4.


                                Что касается PS1 — можно точно так же и поставить, разве что escape-последовательности будут другие

                                Т.е. тоже нельзя? Или есть автоматический перекодировщик escape-последовательностей?


                                Просто чтобы начать я хотел получить какой-то базис: все введенные мной команды никогда не пропадут, плюс привычная расцветка приглашения командной строки.

                                  +3

                                  Если у Вас за 4 года накопилось 117402 команды, то миллиона хватит лет на 40. Можно, конечно, всё-равно продолжать беспокоиться что миллиона может не хватить, но это уже проблема психологическая, а не техническая.


                                  Автоматический перекодировщик чего конкретно? У Вас там ровно три значения: \u — юзер, \h — хост, \w — текущий каталог. Аналогичные три значения можно найти в доке zsh быстрее, чем мы это обсудим в комментах.

                                    0
                                    Если у Вас за 4 года накопилось 117402 команды, то миллиона хватит лет на 40. Можно, конечно, всё-равно >продолжать беспокоиться что миллиона может не хватить, но это уже проблема психологическая, а не >техническая.

                                    Зачем нужны эти подсчеты, тем более что они верны только для одной машины, это домашний ноутбук, сколько на других машинах к которым я имею доступ смотреть нет желания.


                                    Подсчитывать прикидывать, зачем мне это нужно, я хочу сказать shell'у используй сколько нужно и больше не беспокой меня с этим вопросом.


                                    Автоматический перекодировщик чего конкретно?

                                    у меня там еще и цвета, которые закодированы escape последовательностями,
                                    и по вашим словам:


                                    разве что escape-последовательности будут другие

                                    из них я сделал вывод, что и для цветов в prompt zsh требует какие-то свои escape последовательности.

                                      0
                                      из них я сделал вывод, что и для цветов в prompt zsh требует какие-то свои escape последовательности.

                                      Вообще‐то нет, escape‐последовательности можно передавать терминалу как есть, как и в bash, только вместо \[ и \] будут %{ и %}. Но я бы не рекомендовал: оно либо не читаемое, либо вам придётся заводить переменные вроде BLUE_COLOR=$'\e[34m', тогда как zsh предоставляет вещи вроде %F{blue} для раскрашивания.

                                        +2

                                        Для подсветки разными цветами последовательности действительно отличаются, но: во-первых указанные Вами отвечают не за цвета, а за указание терминалу/screen изменить заголовок окна, а они от шелла не зависят и везде будут одинаковые, а во-вторых в bash даже для смены цвета обычно задаются стандартные последовательности, которые не так удобно читать как "%B%F{red}жирный красный%f%b" в синтаксисе zsh, но зато, опять же, они должны работать одинаково в любом шелле, так что если нет желания переписывать их в синтаксисе zsh — их можно просто скопировать как есть.

                                  0

                                  Никогда не задавался такой идеей, хранить историю беконечно). А вообще — man bash


                                  export HISTSIZE=
                                  export HISTFILESIZE=

                                  Тогда не забудьте настроить HISTTIMEFORMAT


                                  Или настройте logrotate, пусть раз в пол года делает архивы, если вам так нужно. В случае поиска воспользуетесь zgrep, zcat

                                    0
                                    Никогда не задавался такой идеей, хранить историю беконечно). А вообще — man bash

                                    Вы комментарий на который отвечаете читаете? Для bash у меня все настроено, и даже настройки
                                    приведены в теле комментария.

                                  0
                                  Да, узнал об этом шелле в этой статье https://habrahabr.ru/post/323496/
                                  Первое впечатление было: «Вау! Крутая штука!»
                                  Но в итоге поигрался пару часиков и вернулся на bash — на моем ноуте zsh тормозит конкретно.

                                  Зато теперь знаю, что крутой промпт в скринкастах на маках — это zsh, а не фича макоси! )
                                  Взял на заметку — придет время обновлять систему (на следующий Ubuntu LTS) попытаю еще раз счастья.
                                    +1
                                    на моем ноуте zsh тормозит конкретно.

                                    Это не zsh. В самом zsh тормозить нечему. Это тормозила чужая навороченная конфигурация с кучей включённых по умолчанию плюшек (вроде oh-my-zsh), которую Вы, вероятно, поставили, чтобы получить "вау-эффект" с первой минуты.

                                      0
                                      Нет, ту конфигурацию я не ставил, установил просто zsh из реп.
                                      Конфиг почти пустой был — вот сейчас проверил (в системе zsh остался, я его не удалял), удалил совсем конфиг и запустил с нуля — тормозит.
                                        0

                                        А можно чуть конкретнее? Что именно тормозит и как Вы это определяете?

                                          0
                                          Набираю команду — после нескольких введенных символов курсор «спотыкается» — фризится, дальше сразу несколько следующих символов появляются и так повторяется в зависимости от длины команды.
                                          Я печатаю вслепую, смотрю постоянно на монитор и такой дерганное отображение раздражает
                                          (в bash'е, естественно, такого нет).
                                            0

                                            А при запуске zsh -f этот эффект тоже наблюдается?
                                            Если нет — проблема в Ваших конфигах zsh, или в ~/ или в /etc/.
                                            Если да — возможно проблема в каких-то общесистемных вещах, но для начала стоит попробовать обновить zsh на 5.2 или более новую версию.

                                        0
                                        Как-то я пересел на зишелл, навключал всяких вау плюшек. Было круто, но вся эта конфа тормозила на макбуке. В итоге соскочил назад на баш, покурил ман и стековерфлоу, реализовал почти все фишки на обычном баше в одном конфиге. Летает мухой.
                                      +1
                                      Если у вас 1000 серверов и везде стоит обычный bash, то какой смысл ставить себе zsh локально? Я не перехожу на zsh в том числе и по этой причине.
                                        +1

                                        1000 серверов управляется ведь не ручками, а через ansible/chef/etc. Так что раскатать на них zsh с вашими конфигами не должно быть проблемой, было бы желание.

                                          0
                                          1000 серверов управляется ведь не ручками, а через ansible/chef/etc.

                                          Не всегда это так. На Хабре очень привыкли к ситуации когда 1000 серверов это: 500 app, 200 nginx, 100 mongo, ну и инфраструктура на сдачу.


                                          Но в ентерпрайзе эта 1000 серверов редко имеет что-то общее, кроме как: там установлен Linux. А однотипных приложений редко больше пары десятков. В такой ситуации нахождение общих паттернов задача весьма не простая. Как это происходит я выше описал.

                                            0

                                            Общие паттерны здесь не при чём. Хотя они всё-равно всегда есть, просто относятся к инфраструктуре, а не основной задаче сервера: логи, бэкапы, обновления, добавление аккаунтов для новых сотрудников, etc. И если сервер умер или его надо обновить/переустановить — Вы предпочтёте разыскивать уволившегося два года назад сотрудника, который знал что/как/почему надо настраивать на этом сервере, или всё-таки запустить плейбук ансибла который тупо раскатает на новый сервер всё, что необходимо — пусть даже этот плейбук нужно было когда-то написать конкретно для этого сервера?

                                              0

                                              Да чтож такое, почему на Хабре принято читать только свои комменты :(


                                              Раскатка нового сервера это первое что автоматизируется. В интерент проектах это важный кусок работы (поскольку раскатка идет часто, сервера однотипные). Но в ентерпрайзе это мизер. Он автоматизирован, поскольку его легко автоматизировать, но это дай бог 2-3 процента работы. Аналогично заведение нового пользователя. Вы сейчас гововорите о мелочах, которые автоматизированы буквально у всех.


                                              А вот например, клонирование крупного софта (OEBS или SAP), проведние каких-то особых операций с этим софтом автоматизируется со скрипом: редкие операции над большим количеством компонент, высокая вариативность настроек от сервера к серверу. На нахождение именно этих патернов уходят долгие годы. Потом они закрепляются в том же ansible или даже в продуктах Oracle (Rapid Clone хороший пример этой истории).


                                              Т.е. сумируя: если на старте вы точно знаете что делать и видите все точки ветвления в операции — то сразу пишите ansible скрипт, если вам сказали иди туда не знаю куда, возьми индускую документацию и сделай, то сначала вы сделаете, а потому уже будете автоматизировать, поскольку вам снача нужно набить експу и понять как это работает.

                                                0

                                                Угу. Только свои комменты. Именно. У нас здесь вообще-то есть определённый контекст, и обсуждаем мы не SAP. Какое отношение описанное Вами имеет к сложности/неприемлемости установки zsh на 1000 разношёрстных серверов в энтерпрайзе?

                                                  0

                                                  Ну да, пожалуй флейм, согласен.

                                        +4
                                        Лучше на дефолте, но зато везде одинаково, чем тут zsh, а везде bash и ругайся потом, что чего-то работает не так, как ты привык. Пожалуй это главный аргумент в пользу оставить всё как было.
                                          +2
                                          Да не дает особо крутых каких-то нехватающих уберфич этот zsh.
                                          Подсветка синтаксиса настраивается и так, полно скриптов в bashrc.
                                          Редактирование команд и интеграция с редактором — продвинутые парни используют vim/emacs mode для bash
                                          Автодополнение — так по неизвестным командам все равно открываешь man, часто используемые команды заносятся в алиасы, а для совсем экзотических случаев есть bash-completion.
                                          Хитрое скриптование — так это вообще не задача шелла, нафига его использовать не по назначению, если есть профессиональные инструменты perl/python.
                                            0
                                            продвинутые парни используют vim/emacs mode для bash

                                            emacs mode это дефолт так то. Можно включить vim mode, но даже мне, любителю vim, этот режим неудобен.
                                            для совсем экзотических случаев есть bash-completion.

                                            скорее наоборот, для экзотики man, а обычно всё автодополняет именно bash_completion.
                                            Хитрое скриптование — так это вообще не задача шелла

                                            не соглашусь. bash вполне удобен для написания скриптов. Я бы не тянул повсеместно другие языки для того, что можно быстро написать на bash.
                                              +1
                                              Ну скриптуйте и получайте несовместимый код. По мне идеология баша, когда все- текст, самый приемлемый вариант для инструментов такого типа, не нужны в нем никакие хеши, даже массивы излишни. Для всего ведь есть свой инструмент, а так можно и на sed/awk полноценные программы писать.
                                              0

                                              Какая ещё подсветка синтаксиса в bash? Никогда не видел таких скриптов.


                                              Про «интеграцию с редактором» в zsh тоже. Вот для приложений на основе readline кто‐то создал библиотеку, которая позволяет использовать Vim (реальный Vim, а не неполноценную эмуляцию в виде vim mode) для редактирования. ZLE — это собственная альтернатива readline от авторов zsh, а не какой‐то редактор: в виде отдельной библиотеки ZLE не существует.
                                              А Vim/emacs mode с ZLE не сравняться: попытайтесь, к примеру, создать сочетание клавиш для вставки из буфера обмена в уже экранированном виде. Или ещё интересный запрос: хочется написать zmw *.c *.c.bak и переименовать все файлы *.c в *.c.bak. Нет, с экранированием и специальным¹ скриптом/приложением такое можно сделать. Я спрашиваю, как это сделать без того, чтобы я использовал экранирование.


                                              Ваша претензия к автодополнению тут не в тему, совершенно. В zsh это гораздо шире: его можно использовать для поиска файлов (к примеру, /u/b/z<Tab> можно дополнить до /usr/bin/z и дальше он будет предлагать варианты на z), оно работает внутри различных синтаксических конструкций ($V<Tab>, $(e<Tab>), $(e<Tab> (я не зря указал оба варианта, проверьте их оба в bash как следует)), оно умеет убирать (или не убирать, если вам не нравится) ненужные косые черты при автодополнении каталогов (я имею ввиду, вы написали cmd<Space>dir<Tab><Space>foo и получили cmd directory foo, а не cmd directory/ foo). Именно man мне автодополнение почти никогда не заменяет, но на bash я его не променяю.


                                              Хитрое скриптование — оно у zsh вообще‐то больше заточено под write-only однострочники и это как раз задача shell. Скрипты с некоторыми возможностями zsh получатся не слишком читаемыми и их лучше писать больше похожими на bash‐скрипты.


                                              ¹ zmv — это функция zsh, zmw — это моё что‐то вроде alias’а noglob zmv -W, только noglob меня чем‐то не устроил…; впрочем чем меня не устроил noglob — не важно, да я и не помню — в bash такого временного модификатора всё равно нет.

                                                –1
                                                Я не пытался сделать какие-то претензии к zsh, я просто хочу показать, что его функционал излишен для выполнения работ на удаленных машинах в целях системного администрирования. Давайте я попробую парировать ваши утрверждения.

                                                Какая ещё подсветка синтаксиса в bash? Никогда не видел таких скриптов

                                                Догадываетесь почему? Потому что это нафиг никому не надо — смотреть в непонятный пестрый экран. Там, где это действительно надо (редакторы), это делается другими инструкментами. А вот если вы погугите немного в этом направлении, найдете очень много хитрых решений в bashrc для этого функционала. Вчера только свежий дебиан 8.4 ставил на одну из ВМ, там в консоли уже по умолчанию все цветное (если xterm-256color).

                                                попытайтесь, к примеру, создать сочетание клавиш для вставки из буфера обмена в уже экранированном виде

                                                А зачем? Люди используют удаленные сессии, как там вообще может удаленный zsh перехватывать буфер обмена? Если вы пользуетесь действительно таким функционалом, вам гораздо быстрее написать скрипт экранирования и сделать в консоли что-то вида echo <Shift-Ins> | escape

                                                хочется написать zmw *.c *.c.bak и переименовать все файлы *.c в *.c.bak.

                                                Не хочется. Для этого я запущу find или xargs, а в самом сложном варианте сделаю через однострочних в цикле for.

                                                его можно использовать для поиска файлов

                                                вот попробуйте испоьзовать этот прием на рабочем сервере с миллионом (или сколько там ограничение у разных fs) файлов. Вы в таких случаях отучитесь вообще пробовать у шелла автодополнение. Попробовать такое на embedded дистрибутивах также вам доставит удовольствие.

                                                оно работает внутри различных синтаксических конструкций

                                                А зачем? В однострочниках переменные называются интуитивным образом, их не надо дополнять. В многострочниках это задача редактора.

                                                Хитрое скриптование — оно у zsh вообще‐то больше заточено под write-only однострочники

                                                Так я это и не отрицаю. Просто каждому хотелось бы, чтобы write-only рецепт сработал как на нагруженном сервере, так и на очередной поделке с dd-wrt, так и на локальной машине. А учить для одного сервера zsh, для того, чтобы на сотне других пользоваться bash, как-то уже совсем не то.

                                                Наверно, zsh хорошо подходит, если много работаешь именно на локальной машине. Но перекрыть его возможности обычным башем также с легкостью можно.

                                                Ну и в догонку — согласно вики zsh был запущен в лохматом 1990, я с ним плотно игрался в 2008-2009 (припоминаю, там еще были косяки по unicode). За все это время с развитием технологий виртуализации, автоматической настройки серверов, я не встречал ни одной крупной организации, где бы в init скриптах на создание очередного сервера стояла автоматическая установка zsh. Я полагаю, это не просто так.

                                                Shell должен работать быстро везде (за исключением машин в Австралии или подключенных через спутниковый канал=), если появляется лишняя непредсказуемая задержка — она уже сама наводит панику, что какую-то команду я ввел зря.
                                                  0
                                                  Я не пытался сделать какие-то претензии к zsh, я просто хочу показать, что его функционал излишен для выполнения работ на удаленных машинах в целях системного администрирования.

                                                  Хм. А почему Вы для таких работ используете bash, ведь есть же sh? Разве функционал bash не излишен примерно в той же степени, что и zsh?


                                                  Догадываетесь почему? Потому что это нафиг никому не надо — смотреть в непонятный пестрый экран.

                                                  Звучит как "виноград кислый", если честно. Я, лично для себя, пока ещё не определился, нравится мне подсветка синтаксиса или нет (но скорее всего надо просто немного поднастроить цвета, может отключить подсветку отдельных элементов). Но я не вижу абсолютно никакой проблемы в том, что при наборе на удалённом сервере я сразу вижу есть ли опечатка в имени команды или не закрытые кавычки, ещё в процессе набора, до запуска команды. Если оно из коробки "пёстрое" — ну так подправьте цвета под свой вкус, отключите подсветку лишних элементов, но в самой идее подсветки синтаксиса абсолютно ничего плохого нет, и продуктивность это обычно повышает.


                                                  Люди используют удаленные сессии, как там вообще может удаленный zsh перехватывать буфер обмена?

                                                  Хрен его знает. :) Но я только что проверил — через ssh работает, а в screen (даже локальном) — нет.


                                                  Не хочется. Для этого я запущу find или xargs, а в самом сложном варианте сделаю через однострочних в цикле for.

                                                  А мне вот хочется. Вероятно, это дело вкуса. Я линух админю уже 23 года, но параметры find для меня так и не стали интуитивно понятными, что-то чуть нетривиальное — приходится сначала лезть в man, а потом ещё и экспериментировать немного, чтобы убедиться что команда возвращает нужные файлы. Так что возможность использовать find значительно реже — для меня выглядит довольно привлекательно.


                                                  вот попробуйте испоьзовать этот прием на рабочем сервере с миллионом (или сколько там ограничение у разных fs) файлов. Вы в таких случаях отучитесь вообще пробовать у шелла автодополнение. Попробовать такое на embedded дистрибутивах также вам доставит удовольствие.

                                                  Практически всё, что даёт удобный интерфейс и облегчает жизнь пользователя — делает это за счёт большего количества вычислений, т.е. потерь производительности. Обычно это не заметно, потому что время реакции человека меньше этих задержек. Но, да, бывают крайние случаи когда это заметно. И если Вы 90% своего времени выполняете команды в каталоге с миллионом файлов или на невероятно медленном устройстве — zsh тут действительно будет неуместна. Но, как правило, 90% своего времени проводится вовсе не в таких условиях, и проще быть осторожнее в набираемых командах когда изредка оказываешься в таких условиях, чем лишать себя удобств во всё остальное время.


                                                  А зачем? В однострочниках переменные называются интуитивным образом, их не надо дополнять.

                                                  Дополнять надо всё. Во-первых потому, что это проще и быстрее, но важнее то, что это мешает делать опечатки.


                                                  Просто каждому хотелось бы, чтобы write-only рецепт сработал как на нагруженном сервере, так и на очередной поделке с dd-wrt, так и на локальной машине.

                                                  Да. К сожалению, мир устроен иначе. Я вот изредка попадаю на сервера где нет bash. И половина набираемых мной команд, внезапно, перестаёт работать как ожидалось. Знаете, что я в этот момент делаю? Устанавливаю, с матами, bash. А ещё bash бывает разных версий, так что часть привычных конструкций изредка на древних серверах выдаёт не то, что ожидается (такое бывает не часто, да, но всё-равно). Так что Ваша мечта всегда будет только мечтой, к сожалению.


                                                  А учить для одного сервера zsh, для того, чтобы на сотне других пользоваться bash, как-то уже совсем не то.

                                                  Вот! Именно это и удерживало меня от изучения zsh долгие годы. И именно про это написана статья — чтобы показать, что отличий между bash и zsh не так много, что "учить zsh" это не так масштабно и сложно как кажется на первый взгляд, что практически все команды которые работают в bash будут ровно так же работать в zsh (а если включить SH_WORD_SPLIT — тогда, думаю, вообще все в которых не встречается $BASH…).


                                                  Запомнить что в bash нельзя пользоваться флагами/квалификаторами/модификаторами несложно, и даже если что-то такое набрать по привычке случайно в bash — будет не трагедия, а синтаксическая ошибка (как и для сокращённых вариантов if|while|for). Автодополнение в bash будет работать хуже, но это тоже не помешает набирать корректные команды. По большому счёту, основное что может создать проблему помимо SH_WORD_SPLIT — это шаблоны с <число1-число2>, которые bash скорее всего поймёт как перенаправление stdin/stdout.


                                                  Если нужно много работать с bash, то Вам никто не мешает включить SH_WORD_SPLIT и забыть про возможность использовать <число1-число2> в шаблонах. Тогда шанс, что привычная по zsh команда некорректно заработает в bash, будет пренебрежимо мал. В общем-то, именно для таких ситуаций в zsh и существуют эти 177 опций, кардинально влияющие на поведение и поддерживаемый синтаксис — чтобы каждый мог работать в такой zsh, которая подходит лично ему, а не в такой же zsh, как у всех.


                                                  Наверно, zsh хорошо подходит, если много работаешь именно на локальной машине.

                                                  Да. Но, в идеале, на серверах вообще нежелательно ручками работать, для этого есть ansible/chef/etc. Идеал не всегда достижим, конечно, но общая тенденция идёт в этом направлении. Приложения расползаются по docker-контейнерам, в которых вообще не то, что bash, но даже и sh может не быть (хотя бы из соображений безопасности).


                                                  Но перекрыть его возможности обычным башем также с легкостью можно.

                                                  Это прямая ложь, нехорошо, однако.


                                                  я с ним плотно игрался в 2008-2009 (припоминаю, там еще были косяки по unicode)

                                                  Да, судя по changelog — было такое. Но сейчас вроде всё ок, так почему наличие багов 8 лет назад является проблемой сейчас?


                                                  За все это время с развитием технологий виртуализации, автоматической настройки серверов, я не встречал ни одной крупной организации, где бы в init скриптах на создание очередного сервера стояла автоматическая установка zsh. Я полагаю, это не просто так.

                                                  Как я уже выше упоминал, чем дальше мы идём по тропинке виртуализации, увеличения количества серверов и сужения выполняемых ими задач — тем меньше смысла выполнять на этих серверах команды вручную по ssh, они должны управляться через ansible etc. Поэтому там и bash нередко избыточен, не говоря уже про zsh. Так что да, это не просто так.


                                                  Shell должен работать быстро везде (за исключением машин в Австралии или подключенных через спутниковый канал=), если появляется лишняя непредсказуемая задержка — она уже сама наводит панику, что какую-то команду я ввел зря.

                                                  Угу. Но я пока от zsh задержек не наблюдал. Допускаю, что они бывают, вот эта настройка в oh-my-zsh наводит на такую мысль (но здесь подразумевается индикация причины задержки, так что всё вроде ок):


                                                  # Uncomment the following line to display red dots whilst waiting for completion.
                                                  COMPLETION_WAITING_DOTS="true"
                                              +1

                                              Это скорее относится к скриптам. Скрипты я на zsh писать тоже не планирую, именно по этой причине. А вот интерактивные фичи zsh значительно увеличивают удобство работы, к некоторым привыкаешь моментально.


                                              Например, что вставка из clipboard нескольких строк теперь не начинает молча выполняться, а просто показывает вставленный текст и ждёт подтверждения Enter-ом для его запуска; очень быстрая навигация по каталогам — у меня по Ctrl-Shift-Left|Right перебираются последние каталоги (причём не затирая текущую частично набранную команду — изменяется только имя каталога в приглашении перед командой), по Alt-q можно "отложить" текущую набранную команду, выполнить вместо неё другую и тут же автоматически продолжить редактировать отложенную команду с курсором в том же месте, в bash после прерывания по Ctrl-C некоторых команд состояние терминала портилось и нужно было вслепую запускать reset — а в zsh этого не просходит… и там много ещё такого всякого. Давеча у меня rm * внезапно спросил подтверждения… оказывается, есть и такая фича, специально для ситуации когда rm получает одним из аргументов *. В общем, приложение изначально заточенное сделать тебе "удобно" в интерфейсе, и не заточенное — это две большие разницы, и чувствуется это в куче разных мелочей.


                                              Я не хотел всё это перечислять в статье, потому что то, что одному удобно — другого только раздражает, но суть в том, что в zsh слишком много всего и каждый может сделать намного удобнее лично для себя. А к заметно более удобному привыкаешь моментально… так что выкатывание zsh со своими конфигами на сервера становится вопросом времени. :)

                                                0
                                                Это скорее относится к скриптам. Скрипты я на zsh писать тоже не планирую,

                                                Но ведь есть одно строчные скрипты, типа


                                                for i in *.jpg; do convert -resize 200x200 $i /tmp/res/`basename $i`.png; done

                                                т.е. какое-то знание о while/for/if/ нужно, иначе как скажем применить несколько команд к определенным (не всем) файлам в директории.

                                                  0

                                                  И что? Такой bash/sh синтаксис zsh понимает и так, у него очень сильная совместимость с другими шеллами. А вот если вы привыкнете в zsh писать в сокращённой форме:


                                                  for i in *.jpg; convert -resize 200x200 $i /tmp/res/`basename $i`.png
                                                  # или даже
                                                  for i in *.jpg; convert -resize 200x200 $i /tmp/res/${i:t}.png

                                                  то всё, что вам грозит при попытке запустить это в bash:


                                                  -bash: syntax error near unexpected token `convert'

                                                  В общем, если честно, я не вижу трагедии. Ладно шелл, но вот пользоваться на других машинах редактором-убожеством вроде mcedit, nano или не настроенного vim — я "пас" в любом случае. А раз всё-равно приходится везде носить свои настройки для vim, то добавить к ним ещё и настройки для zsh — не сложно.

                                                  +1
                                                  вставка из clipboard нескольких строк теперь не начинает молча выполняться, а просто показывает вставленный текст и ждёт подтверждения Enter-ом для его запуска;

                                                  давно я не копировал в терминал что-то, чтобы выполнить. А на боевом сервере я бы не рискнул такое делать даже зная, что zsh не выполнит вставленное.
                                                  очень быстрая навигация по каталогам — у меня по Ctrl-Shift-Left|Right перебираются последние каталоги (причём не затирая текущую частично набранную команду — изменяется только имя каталога в приглашении перед командой)

                                                  в inputrc (где удобно, глобальный или нет) вписываем следующее:
                                                  "\e[A": history-search-backward
                                                  "\e[B": history-search-forward
                                                  "\eOA": history-search-backward
                                                  "\eOB": history-search-forward
                                                  

                                                  теперь начинаем вводить команду и жмём стрелочку вверх — введённый текст не затирается, в истории ищутся последовательно все команды, которые начинались так же. Так же знаю ещё одну фичу zsh — он ходит по каталогам не взирая на case символов, для этого в баш есть такое:
                                                  set completion-ignore-case On
                                                  

                                                  теперь cd movies или Movies — не важно, если совпадение по буквам единственное — bash его заполнит.
                                                  по Alt-q можно «отложить» текущую набранную команду, выполнить вместо неё другую и тут же автоматически продолжить редактировать отложенную команду с курсором в том же месте

                                                  sudo apt insta^U
                                                  вводим новую команду
                                                  ^Y
                                                  готово.
                                                  в bash после прерывания по Ctrl-C некоторых команд состояние терминала портилось и нужно было вслепую запускать reset

                                                  достаточно редкое явление, чаще всего ^L помогает.

                                                  Вот и в bash я уже привык ко всему и не вижу смысла везде тащить zsh, тем более, что киллер-фич не особо густо, на самом деле.
                                                    0

                                                    Удобство создаётся не какой-то киллер-фичей, а множеством разных мелочей.


                                                    Лучше на дефолте, но зато везде одинаково, чем тут zsh, а везде bash и ругайся потом, что чего-то работает не так, как ты привык. Пожалуй это главный аргумент в пользу оставить всё как было.

                                                    Я про это отписался выше: настройте zsh опциями так, чтобы максимально эмулировать поведение bash, забудьте про одну-две фичи zsh которые могут создать проблемы в bash — и вы получите большую часть доступных удобств zsh без создания себе проблем при наборе привычных по zsh команд в bash.

                                                    0
                                                    очень быстрая навигация по каталогам — у меня по Ctrl-Shift-Left

                                                    Как это включить?
                                                      0

                                                      Подключить плагин dircycle из oh-my-zsh.

                                                  0

                                                  Вся эта история вокруг bash/zsh напоминает обсуждения какие обои и какие виджеты должны быть на рабочем столе. Начисто игнорируя то, что реальная работа происходит не на рабочем столе и не в bash/zsh.

                                                    0
                                                    Есть люди, которые в терминале проводят очень много времени, и от удобства терминала зависит их продуктивность. Некоторые люди предпочитают копировать файл из директории A в директорию B с помощью mc и тратят на эту операцию иногда по несколько минут. Даже зная, что с помощью bash это сделать можно за несколько секунд, все равно предпочитают mc, потому что он дает им лучшее понимание контекста. Мне нравится zsh ровно тем, что повышает продуктивность (выполняю больше действий в единицу времени), дает лучшее понимание контекста (где нахожусь, какой бранч в git'е, есть ли изменения), экономит время (не надо запускать time, если кто-то работал медленно) и еще много приятных плюшек.
                                                    0
                                                    В правильной статье про zsh должны быть скриншоты/гифки с демонстрацией того, как это работает.
                                                      0

                                                      Спасибо за статью!

                                                        0

                                                        В посте тема дополнения особо не затрагивалась, но я бы добавил, что есть такой виджет дополнения как _complete_help, который покажет нынешний контекст, а с NUMERIC ещё и используемые стили.


                                                        Вместо ручного ввода escape-последовательностей в zkbd можно их получить модулем terminfo (http://zshwiki.org/home/zle/bindkeys#reading_terminfo).

                                                          0

                                                          С вариантом на terminfo есть свои проблемы (конкретно в моём случае).
                                                          Во-первых, я начитался про то, как у людей подтормаживает zsh при запуске из-за большого количества подключённых модулей/плагинов, поэтому стараюсь изначально не подгружать то, без чего можно обойтись.
                                                          Во-вторых, в $terminfo есть далеко не все кнопки, например как через него получить код для Ctrl-PageUp?
                                                          В-третьих, у меня в ~/.Xresources есть немаленький блок строчек URxvt.keysym.* задающий конкретные escape-последовательности конкретным кнопкам (без этого часть комбинаций не работает в Vim)… и что-то я сомневаюсь, что $terminfo будет возвращать именно эти комбинации, это было-бы как-то уж слишком волшебно.
                                                          Ну и в последних — у меня не так много разнотипных серверов, везде примерно одно и то же, так что файл с результатом zkbd попадёт на сервера вместе с остальными конфигами zsh и будет, я полагаю, вполне корректно работать везде, без необходимости вызывать zkbd на каждом сервере отдельно.

                                                            0
                                                            Во-вторых, в $terminfo есть далеко не все кнопки, например как через него получить код для Ctrl-PageUp?

                                                            Но кнопки без модификаторов присутствуют. Присутствуют даже некоторые с модификаторами (Ctrl-Left, Ctrl-Right, Shift-Tab). zkbd не спрашивает Shift-Tab.


                                                            В-третьих, у меня в ~/.Xresources есть немаленький блок строчек URxvt.keysym.* задающий конкретные escape-последовательности конкретным кнопкам (без этого часть комбинаций не работает в Vim)… и что-то я сомневаюсь, что $terminfo будет возвращать именно эти комбинации, это было-бы как-то уж слишком волшебно.

                                                            Не будет, пока вы не измените соответствующий capability и не перекомпилируете утилитой tic. Зато эти изменения станут видны другим программам, полагающимися на terminfo.

                                                          0

                                                          del

                                                            +1

                                                            Спасибо за интересную статью и очень интересные комментарии к ней.
                                                            Более 2 лет пользуюсь fish shell дома и на рабочем ноуте, ну а баш на удаленных серверах.
                                                            К фишу привык, его почти не нужно настраивать, но так как он почти совсем не совместим с баш/сш то посматриваю в сторону zsh.
                                                            Если вдруг кому интересны мои настройки, то они располагаются на github
                                                            Ну а вот как выглядит конечный результат(fish — зеленые часы и стрелочка, bash — голубые, zsh — желтые)
                                                            image

                                                              0

                                                              Блин забыл картинку под спойлер засунуть, простите

                                                              0
                                                              Похоже правильное место для моего вопроса. Как выставить приоритет в автодополнении zsh, чтобы каталоги подставлялись до команд? Иногда хочется перейти в каталог, но есть куча команд с похожим названием и это мешает.
                                                              Пример
                                                              image
                                                                0

                                                                Попробуйте это (возможно стоит указать только local-directories, а остальное выкинуть):


                                                                zstyle ':completion:*:*:-command-:*:*' group-order \
                                                                    local-directories directory-stack named-directories directories
                                                                0

                                                                А по мне — так только в линуксе я перестал каждый раз полдня настраивать прочее окружение. 15 галочек там, 25 здесь, поставить то, это…
                                                                Независимо от консоли линукса, в которой я нахожусь, я все могу делать сразу. И во многом это заслуга именно bash. На любом сервере я могу сразу работать, не испытывая неудобства по поводу, например, того самого чудесного автодополнения или ещё какой чудо-фичи, настроенной под меня за полдня подготовки рабочего места к собственно работе...

                                                                  +2

                                                                  Почему бы вам не попробовать сохранять ваши dotfiles где-нибудь на github?
                                                                  Две-три команды и у вас ваше окружение на любом компьютере.

                                                                    +1
                                                                    Проблема в том, что сервера не принадлежат единственному и неповторимому админу (мне), туда ходят минимум 5 коллег со своими представлениями об удобстве.
                                                                    bash в этом случае — достаточно приличный компромисс, после установки bash-completion, который достаточен для выполнения админских задач.

                                                                    На локалхосте или сервере, где ты _единственный_, кто туда ходит — без проблем, хоть sh, хоть tcsh, хоть zsh. В случае сервера, куда рутом ходят только в случае проблем, zsh с чужими настройками — помеха, а не помощь.
                                                                      0
                                                                      Соглашусь с предыдущим оратором. У меня есть домашняя рабочая станция, есть рабочая. А есть несколько десятков серверов, куда я никакие dotfiles тащить не буду ни в коем случае.
                                                                      Посыл был именно в том, что мне не надо привыкать ни к чему — везде одна среда.
                                                                        0
                                                                        и да, dotfiles и прочие плюшки home-каталога у меня ездят между рабочими станциями. Потому что это моё, и если что-то пойдёт не так, то это мои личные проблемы, а не проблемы моего работодателя.
                                                                    0

                                                                    Имхо, не могу представить реальную необходимость в переходе на zsh.
                                                                    Ну да, есть прикольные фишки, интерактивные подсветки, расширенные автодополнения по аргументам комманд и прочее. Но есть ли в этом реальная необходимость? Я думаю — нет.
                                                                    Вот один из аргументов почему:
                                                                    По долгу работы, да и вне ее, провожу большую часть времени в консоле. Многие недооценивают возможности bash, как мне кажется, по навигации, дополнению, истории и пр.
                                                                    Не было у меня еще в реальной жизни задачи, с которой бы не справился bash или bash был бы не удобен. А человеки ставят zsh только потому, что это больше по-гиковски, нежели из-за реальной необходимости, имхо. Во всяком случаи вот такие статьи и аналогичные на хабре, только лишний раз это подтверждают. Ну не нужны все эти красивости в реальной работе, не нужны).
                                                                    Все аргументы команд, которые более-менее часто используется, наберется около двух сотен. Все их аргументы, лично я, знаю. Даже не так, знаю, конечно, наизусть далеко не все, но подавляющее большинство, которые мне реально необходимы в работе, знаю.
                                                                    Ведь реальная работа в консоле, сводится к чаще всего однообразным действиям, с одинаковыми ключами, типа ps aux или du -h --max-depth=1 | sort -rh
                                                                    утрированно, но все же. Большинство из висят на альясы или написаны нужные мне функции.
                                                                    И все эти красивости, в виде подсказки в виде 38 различных флагов ls или весь список параметров netstat, ну реально, это так действительно необходимо?
                                                                    Ну надо что-то мне вспомнить: ctrl+| (открывает сплит в терминале справа), man netstat, /search_string, q, ctrl-d.
                                                                    Отрывать руки от клавиатуры на мышку? Да нет, конечно. Даже по навигации в текущей строке — никаких стрелочек, как и для истории. Надо написать длинную команду — Ctrl-x Ctrl-e и я в родном vim. Все это функционал bash.
                                                                    Это лишь частный пример, по многим другим пунктам аргументы будут аналогичные.
                                                                    Я пользовался zsh около года, печеритал толстенную доку по нему, перечитал большинство статей на хабре, но так и не понял, зачем он мне вместо баша. Безусловно, zsh функционален, красив и вообще как-то по-гиковски. Но нужен ли он в реальном использовании? Мое мнение, что для большинства даже матерых линуксоидов — нет. При должном освоение даже функционала bash-а за глаза.

                                                                      0

                                                                      Плюшки по сохранению вводимой команды, чтобы не потерять ее в bash — Esc+#, да не буду я тут всего перечислять, просто комментарии читаю, вижу что просто не достаточно народ возможности bash знает.
                                                                      Синтаксический сахар zsh — ну прикольно, реально необходимо — совершенно нет.
                                                                      Прыжки по истории каталогов — pushd, popd, dirs, пусть это не настолько удобно как стрелочками листать каталоги, но и не нужно это).
                                                                      Скрипты на zsh в практическом применении не переносимы, из-за отсутствия по-умолчанию в большинстве дистрибутивов этого шела.
                                                                      В общем это развлекуха, а большинство красивостей и удобств есть в bash, быстрей переход по каталогам, insensitive-case, небольшие опечатки — все это можно включить.
                                                                      Зато это единое окружение, которое присутствует везде. И вы не останетесь без своих няшек, когда зайдете на удаленный сервер, где по миллионам причин нет необходимости/разрешения устанавливать дополнительные шелы чтобы вам было удобнее.

                                                                        +1

                                                                        Реальной необходимости нет в абсолютном большинстве нововведений. Любая ОС 15-ти летней давности содержит всё реально необходимое для работы. Даже в хабре нет реальной необходимости для работы "большинства матёрых линуксоидов"… но, тем не менее, Вы зачем-то тут читаете статьи и даже комментируете (а была ли реальная необходимость в Вашем комментарии?). Что касается "красивостей" — то же можно сказать и про абсолютное большинство книг/фильмов/картин/музыки — реальной необходимости в них нет. (Кстати говоря, если говорить абсолютно честно и искренне, не принимая во внимание желание оправдать получаемую зарплату — а есть ли реальная необходимость в большей части Вашей работы? Вы действительно каждый день делаете то, без чего нельзя обойтись, ваши проекты и сервера действительно реально необходимы человечеству?)


                                                                        Суть в том, что нет реальной необходимости ограничивать себя реально необходимым минимумом, если можно сделать красивее, удобнее, интереснее… Иногда это вредит продуктивности, иногда помогает, но продуктивность — в любом случае не самое главное в жизни.


                                                                        P.S. Что касается "я матёрый линуксоид, знаю все нужные флаги" — когда на глаза регулярно попадается список флагов при автодополнении, то даже матёрому линуксоиду это позволяет регулярно открывать для себя новые флаги и возможности, без которых можно было бы обойтись, конечно, но которые могут быть полезны/удобны. Я вот полностью список флагов ls и многих других базовых команд первый и последний раз читал примерно в 1994, когда осваивал линух. После этого у меня всегда было чем заняться и без перечитывания этих man-ов в поисках "а нет ли там чего полезного, чего не было в 1994 либо что я в 1994 не оценил/не запомнил".

                                                                          0

                                                                          Ну не правы вы. Упускаете своло реальной необходимости. Что такое реальная необходимость: есть инструмент и он не справляется со своими задачами. Вы считаете что я в своем настроенном шеле менее продуктивен чем вы? А что вы под продуктивностью понимате? Быстрее сделать то, что смогу сделать я? Напечатать укороченную конструкцию или написать конвеер с командами и их аргументами? Ну тут я бы с вами поспорил. А может вы набираете со скоростью в трое ниже чем я. Тогда кто будет продуктивней? А руку в сторону стрелочек снимаете при навигации? Тоже время тратите. Это все очень субъективно. Я лишь высказал свое мнение, на основе достаточно длительного опыта, что в реальном использовании bash не менее продуктивен, точнее так: не настолько менее продуктивен, чтобы ради этого переходить на не дефолтный шел, изучать новый диалект и просто тонну документации по функционалу zsh и еще столько же по кучи плагинов.

                                                                            +2
                                                                            … в реальном использовании bash … не настолько менее продуктивен, чтобы ради этого переходить …

                                                                            С этим я соглашусь. Но это не значит, что переходить нет смысла. Переход на zsh — вопрос не продуктивности, а удобства. И даже если через год вернуться на bash, то оно всё-равно того стоит, потому что вернётесь Вы уже с пониманием, что и как можно сделать удобнее лично для Вас, и часть этого действительно получится реализовать в bash — так что время потраченное на изучение и использование zsh не пройдёт даром (потому что в результате Вам станет удобнее работать в bash).


                                                                            Вообще, bash штука странная. Умение писать на нём скрипты — является скорее минусом, потому что как только эти скрипты выходят за пределы лично ваших компов, то вас (почти) сразу начинают тыкать носом в "башизмы" в этих скриптах и просить переписать их так, чтобы они работали на любом sh (мне пришлось даже тулзу checkbashisms поставить для упрощения этого процесса). То, что bash "везде установлен" — вообще-то не является правдой, в BSD его обычно из коробки нет, в некоторых линухах вроде OpenWRT тоже нет, etc. А то, что его обычно первым делом устанавливают — ну так ровно с тем же успехом можно было и zsh поставить. Но даже если bash из коробки есть, то вот пакет bash-completion уж точно из коробки отсутствует — а Вы вроде не отрицаете реальную необходимость автодополнения для bash. И снова, в чём принципиальная разница между необходимостью на каждой системе первым делом ставить пакет bash-completion или пакет zsh? То, что "bash везде одинаковый" — тоже не правда, потому что тогда Вам нужно перестать использовать все alias-ы и дополнительные keybinding-и в inputrc. "Голый" bash, без алиасов в .bashrc, без автодополнений и keybinding-ов, который есть почти но всё-равно не везде — это действительно то, чем Вы бы хотели ежедневно пользоваться? И чего ради, чтобы не устанавливать ни одного лишнего пакета, который не нужен для выполнения основных функций сервера?


                                                                            На мой взгляд в отношении bash/zsh основная проблема скорее в инерции мышления и консерватизме, нежели в реальных причинах предпочитать bash. Примерно так, как было когда-то, когда сайты дизайнили "под IE" а не по стандартам, потому что "IE есть у всех". Там ситуацию, хоть и с громадным трудом, переломили — потому что были заинтересованные в этом крупные игроки. А в отношении bash/zsh таких нет, если мы хотим чтобы нам же было удобнее, то менять ситуацию (читай — ставить везде zsh по умолчанию, просто из вежливости к коллегам) надо нам самим.

                                                                              0

                                                                              Да я, собственно, во многом согласен с этим. Но до тех пор, пока в большинстве серверных дистрибутивов он не будет по умолчанию, т.е. по де-факто стандартом, то смысла перелазить я не вижу. И слез я с него именно по той же причине, которое удачно совпало с багом, когда при некоторых командах автокамплита крашился zsh. Было это года 3-4 назад. Для себя не вижу реальной необходимости, мои задачи bash решает полностью.
                                                                              Да, много фишек я настроил на основе опыта в zsh и частично он заставил меня лучше изучить возможности bash, которые на тот момент я сильно недооценивал.

                                                                            0

                                                                            Почти всегда мне не нужно видеть все флаги. Нужно только в случае, когда я что-то ищу, не знаю или забыл.
                                                                            Я сидел на zsh, в чем то вы правы по поводу "находишь что-то новое". Но я нахожу что-то новое, когда целенаправленно читаю man, --help или apropos, что делаю достаточно часто. А когда я начинал осваивать linux, то после какого-то времени, когда уже более-менее ориентировался в консоле, просто дополнял все команды на буквы алфавита, типа a[tab][tab] и по порядку узнавал что есть что. Со временем пробелы заполнялись. Я не могу сказать, что я знаю все команды, да и вряд ли это необходимо. Но не аргумент совсем, что видеть список всех флагов, позволяет открывать для себя что-то новое. Это все зависит от заинтересованности человека. Если человеку это не нужно, он и смотреть этого не будет.
                                                                            Да и может вы давно автокомплит bash не видели?
                                                                            http://i.imgur.com/P15CrxU.png

                                                                              0

                                                                              И что этот автокомплит показывает? Что то я не вижу флагов, вот для сравнения zsh


                                                                              Заголовок спойлера

                                                                              image


                                                                              вот нафига мне такой ущербный автокомплит?
                                                                              К тому же для него все равно надо ставить дополнительный пакет bash-completion, если можно его ставить, ничто не мешает поставить zsh. А для случаев, когда много кто еще заходит — создавайте юзера отдельного

                                                                                –1

                                                                                Да видел все это я). И зачем мне это каждый раз видеть вообще? Серьезно. Если для конкретной ситуации мне нужно применить какую-то опцию, да я сделаю --help. Это случается крайне редко. Большинство параметров к регулярно используемым утилитам я знаю и смогу набрать, даже в отсутствии автокомплита.
                                                                                Я не пытаюсь вас переубедить, лишь высказал свои мысли по этому поводу. Проработав год в zsh, я пришел к выводу, что его функционал более чем избыточен для меня, хотя консоль — мой родной уголок, в котором провожу много времени.
                                                                                Возможно, если кто-то объективно посмотрит на тот функционал, которым реально пользуется и много ли профита с него — придет к таким же выводам.


                                                                                В любом случае, никто не мешает поставить zsh, потратить время, как это сделал когда-то я и сделать вывод: нужны ли все эти плюсы или можно без них обойтись. Но перед этим, очень бы хотелось, чтобы полностью изучили возможности bash, которые явно недооценивают.

                                                                                  0

                                                                                  А мне вот очень даже полезно, лениво набирать --help, да и зачем тратить на это время, или на ман, если просто забыл правильный флаг?
                                                                                  Вот вам не нужен zsh, так зачем комментировать и читать статьи про него?
                                                                                  Я вот прочитал и нашел кучу полезного. Одно то, что zsh подсвечивает неправильно введенную команду красным — иногда может спасти от серьёзных неприятностей. И не говорите мне, что вы никогда не ошибаетесь, идеальных людей не существует

                                                                                    0

                                                                                    Вы часто забываете флаги, так часто что вам при каждом автокоплите нужно это все видеть?


                                                                                    Вот вам не нужен zsh, так зачем комментировать и читать статьи про него?

                                                                                    Тут вообще-то пытаются народ убедить, что стоит переходить на zsh, я высказал свою точку зрения. Может быть кто-нибудь прочтет, да задумается, нужно вообще это ему или нет.


                                                                                    И не говорите мне, что вы никогда не ошибаетесь, идеальных людей не существует

                                                                                    Ну вот представьте, что за десяток лет не было такого у меня, автокомплита по PATH мне более чем хватает.

                                                                                      0

                                                                                      Не верю, что никогда не ошибались. А мне вот не хватает автокомплита по PATH. Все ваши аргументы ничуть меня не убедили, что лучше bash, чем zsh. Потому что если устанавливать bash-completion можно на сервере, то с таким же успехом можно поставить zsh. Никогда у меня не было проблем с установкой других шеллов на серверах поэтому никаких проблем не должно быть у других людей(извините, не удержался, чтобы не показать, как ваши комменты выглядят со стороны)
                                                                                      По поводу надуманной проблемы, что помимо меня еще 5 человек ходит на сервер — так тут вообще для каждого нужно создавать своего пользователя, чтобы потом не возникало вопросов, какой мудак тут натворил делов.

                                                                          0
                                                                          А почему никто не сказал про безопасность?
                                                                          Когда в zsh копируешь строку с переносами, то оно не выполняется по ходу вставки, в отличии от bash, а тихо ожидает дальнейших действий.
                                                                          +1

                                                                          Я смотрю тут одни матерые сисадмины с 100+ чужих серверов собрались. У меня другой сценарий: 6 машин, включая локальную, везде через ansible накатывается плюс-минус один конфиг zsh с плагинами (есть небольшие различия из-за того, что оси разные, все различия также лежать в плейбуках).


                                                                          Все 2 коллеги не против моего конфига, они всегда сидели в дефолтном баше, куча плагинов им при этом не мешает, некоторыми даже пользуются (о которых знают), с парой секунд ожидания на старте мы готовы мириться.


                                                                          На чужих серверах мне редко приходится бывать, да, там не хватает zsh дополнений и прочего, но 99% времени я провожу в настроенных мной терминалах.


                                                                          Согласен, если приходится часто бывать на чужих машинах, лучше привыкать к дефолтам, но зачем ограничивать себя на подконтрольных машинах, если все время сидишь на них — не понимаю.


                                                                          Не исключаю, что все, что нужно можно написать в одном конфиге на bash, но зачем, если можно пользоваться готовым?

                                                                            +1
                                                                            с парой секунд ожидания на старте мы готовы мириться.

                                                                            Если Вы про время старта zsh, то это, вообще-то, проблема решаемая. Я лично не люблю автоматическое обновление плагинов, ни для vim, ни тем более для шелла (помимо прочего, это ещё и немаленькая дыра в безопасности) — я лучше буду делать плагинам git pull когда мне это нужно, ещё и посмотрев при этом git diff. А вот скорость работы я люблю, включая скорость запуска (у меня постоянно запущено под 20 терминалов, и все они автоматом запускаются при загрузке компа).


                                                                            Если выкинуть сложную и медленную логику обновления разных типов плагинов, то всё остальное можно заоптимизировать при желании на пару порядков относительно "самого быстрого фреймворка":


                                                                            % time zsh -i -c 'echo ok'
                                                                            ok
                                                                            
                                                                            0.037 real  0.025 user  0.009 sys  8MB RAM

                                                                            Это скорость запуска весьма навороченного конфига (там только моего кода около 1000 строк, плюс кучка плагинов — zsh-completions, syntax highlighting, частично грузится oh-my-zsh, ну и разная мелочь в количествах).

                                                                              0

                                                                              Спасибо, подебажил свой конфиг (core i5, hdd, ubuntu 16.04, zsh 5.1.1):
                                                                              100 мс — пустой .zshrc
                                                                              350 мс — + пустой antigen && antigen apply
                                                                              450 мс — + тема (powerlevel9k)


                                                                              Дальше была какая-то магия: после комментирования-раскомментирования разных плагинов в итоге получилось так, что вышеописанный конфиг стал грузиться 250 мс.


                                                                              Через какое-то время понял, что включение-отключение тяжелого плагина иногда (не всегда!) оставляет его в кеше, поэтому вашу команду дополнил:


                                                                              rm ~/.*.zwc; time zsh -i -c 'echo ok'

                                                                              Если включить один из плагинов: docker, pip, python, vagrant, хоть один, хоть все сразу — время увеличивалось на 250 мс. Явно что-то там где-то общее подгружается, хотя я заглянул в них (кроме огромного docker) и ничего такого общего не увидел. Почему так может быть?


                                                                              В одном из своих плагинов нашел ошибку, которую я буквально вчера посчитал хорошей идеей: вместо копипаста списка команд своего скрипта я вызывал args="$(myscript help)" и сохранял его в массив, это стоило мне +250 мс.


                                                                              Еще нашел virtualenvwrapper, +250 мс


                                                                              В итоге, удалил свой кривой плагин, удалил pyvirtualenv, получил 320-330 мс стабильных, если включить 4 странных плагина (docker, pip, python, vagrant), то 630-680 мс. В начале было около 1 секунды.


                                                                              Можно ваш конфиг попробовать? Мне кажется, что дело не только в конфиге, что-то у меня еще не в порядке.

                                                                                0

                                                                                zwc удалять не надо, их надо создавать (хотя может и не для всего — для совсем мелких файлов у меня есть подозрение, что zwc только тормозов добавляют).


                                                                                Конфиг мой можно будет увидеть чуть позже, когда я закончу его допиливать и выложу на гитхаб как dotfiles.


                                                                                Для скорости выполнения .zshrc я использую следующие подходы:


                                                                                • не загружать ненужные плагины (банально, да)
                                                                                • стараться запускать как можно меньше внешних команд $(cmd args …) или хотя бы отложить их запуск до момента, когда они реально понадобятся при запуске какой-то команды ручками
                                                                                • если какая-то функция/плагин при загрузке делает сложные расчёты/заполнение больших массовов/хешей (напр. коды для 256 цветов) — скидываю уже заполненный массив/хеш в кеш-файл и при следующей загрузке этой функции/плагина читаю из кеша (при условии, что файл кеша новее файла самой функции/плагина)
                                                                                • подгружаю плагины через свою функцию zsource
                                                                                • вызываю свою функцию zzcompile для:
                                                                                  • файла с кешем completions (.zcompdump) — кеш это хорошо, а хорошо откомпилированный кеш это ещё лучше :)
                                                                                  • самого .zshrc — он у меня пока довольно большой т.к. по сути заменяет фреймворк
                                                                                  • дополнительных файлов крупных плагинов (вроде fast-syntax-highlighting/fast-highlight) которым фреймворк автоматически не делает zcompile

                                                                                zsource:


                                                                                # Ensure sourced file will be loaded faster… at least next time.
                                                                                source $1
                                                                                zzcompile $1

                                                                                zzcompile:


                                                                                # (Re-)Compile source files in background, if needed.
                                                                                [[ $1.zwc -nt $1 ]] || {
                                                                                    sleep 1         # looks like mtime difference must be > 1 sec, or .zwc will be ignored
                                                                                    zcompile -U $1
                                                                                } &!

                                                                                пример использования:


                                                                                autoload -Uz compinit
                                                                                compinit -d $ZSH_CACHE_DIR/zcompdump
                                                                                zzcompile $ZSH_CACHE_DIR/zcompdump
                                                                                ...
                                                                                zsource $BUNDLE/dircycle/*.plugin.zsh
                                                                                zsource $BUNDLE/fast-syntax-highlighting/*.plugin.zsh
                                                                                ...
                                                                                zzcompile $ZDOTDIR/.zshrc
                                                                                zzcompile $BUNDLE/fast-syntax-highlighting/fast-highlight
                                                                                  0
                                                                                  100 мс — пустой .zshrc

                                                                                  Так не должно быть. Пустой это вот так:


                                                                                  % time zsh -f -i -c 'echo ok'                                                                  
                                                                                  ok
                                                                                  
                                                                                  0.002 real  0.001 user  0.000 sys  8MB RAM

                                                                                  Система у меня чуть по-быстрее Вашей (i7 @ 4.5GHz, hdd, zsh-5.2, gentoo), но не настолько же.

                                                                                    0

                                                                                    Нет, это не пустой. Без -f zsh загружает (пробует загрузить) минимум четыре файла: системный zshenv, пользовательский zshenv, системный zshrc, пользовательский zshrc. Ещё четыре, если zsh — login shell. Плюс всё нужно удвоить — есть ещё zwc файлы и zsh обязательно сделает для них stat. 100 мс здесь легко может съесть сильно загруженная (IO) система, с вытесненными из кэша файлами настроек zsh. Хотя у меня с пустым zshrc и echo 1 > /proc/sys/vm/drop_caches по‐прежнему почти ноль:


                                                                                    % time zsh -i -c 'true'
                                                                                    zsh -i -c 'true'  0,00s user 0,00s system 0% cpu 0,011 total

                                                                                    Полагаю, моя система должна быть сильно загруженной для 100 мс. Или есть ещё какие кэши. Или, скорее, в дистрибутиве popstas напихали фигни в /etc/zshrc, а, может, у него просто очень длинная история: моя


                                                                                    % time ( cat ~/.zsh-history/hist | wc -l )
                                                                                    66692
                                                                                    ( cat ~/.zsh-history/hist | wc -l; )  0,00s user 0,02s system 31% cpu 0,063 total

                                                                                     — это 63 мс просто на подсчёт числа строк (15 мс с кэшем) (не хочу проверять в zsh: если ошибусь, её попортит).

                                                                                      0

                                                                                      Система совсем не загружена:


                                                                                      $ free -m                                                                                                                                            
                                                                                                    total        used        free      shared  buff/cache   available
                                                                                      Mem:          24028       14752         217         147        9058        8673
                                                                                      Swap:          4767        3976         791
                                                                                      
                                                                                      $ uptime                                                                                                  
                                                                                       23:04:17 up 17 days,  1:02,  5 users,  load average: 0.07, 0.11, 0.21

                                                                                      Сейчас перепроверил, 0.06 примерно выдает, видимо вчера какие-то zwc тяжелые оставались, все равно в 6 раз больше, чем у вас. Странно…
                                                                                      А с -f тоже по нулям.

                                                                                        0

                                                                                        Нашел, 60 мс добавляет compinit в /etc/zsh/zshrc в Ubuntu 16.04, оно завернуто в условие на переменную skip_global_compinit, я добавил в /etc/zsh/zshenv строчку:


                                                                                        skip_global_compinit=1

                                                                                        После этого конфиг стал грузиться 300 мс вместо 600!
                                                                                        Я почти уверен, что при этом что-то сломалось, но на первый взгляд все дополнения работают, может подскажете, что дает compinit и где искать потерянный функционал?

                                                                                          0

                                                                                          Что даёт compinit написано в man zshcompsys. Если всё работает — вероятно ваш фреймворк тоже вызывает compinit (они все это делают, что характерно) и ничего не потеряно.

                                                                                            0

                                                                                            compinit нужен для работы умного автодополнения. У меня в zshrc он вызывается с ключём -C.


                                                                                            Без кэша compinit должен обойти все места, где есть файлы с описанием автодополнений к разным командам, прочитать (нужна минимум первая строчка) эти файлы и сохранить результат куда‐то внутрь процесса, а так же в файл с кэшем (~/.zcompdump, у меня он 46K). Вот как у меня влияет compinit:


                                                                                            # echo 1 > /proc/sys/vm/drop_caches
                                                                                            % time zsh -f -i -c 'autoload -Uz compinit ; compinit -D'
                                                                                            zsh -f -i -c 'autoload -Uz compinit ; compinit -D'  0,21s user 0,07s system 62% cpu 0,447 total
                                                                                            % time zsh -f -i -c 'autoload -Uz compinit ; compinit -D'
                                                                                            zsh -f -i -c 'autoload -Uz compinit ; compinit -D'  0,15s user 0,03s system 90% cpu 0,199 total
                                                                                            # echo 1 > /proc/sys/vm/drop_caches
                                                                                            % time zsh -f -i -c 'autoload -Uz compinit ; compinit'
                                                                                            zsh -f -i -c 'autoload -Uz compinit ; compinit'  0,04s user 0,01s system 76% cpu 0,065 total
                                                                                            % time zsh -f -i -c 'autoload -Uz compinit ; compinit'
                                                                                            zsh -f -i -c 'autoload -Uz compinit ; compinit'  0,05s user 0,00s system 88% cpu 0,057 total
                                                                                            # echo 1 > /proc/sys/vm/drop_caches
                                                                                            % time zsh -f -i -c 'autoload -Uz compinit ; compinit -C'
                                                                                            zsh -f -i -c 'autoload -Uz compinit ; compinit -C'  0,03s user 0,01s system 70% cpu 0,057 total
                                                                                            % time zsh -f -i -c 'autoload -Uz compinit ; compinit -C'
                                                                                            zsh -f -i -c 'autoload -Uz compinit ; compinit -C'  0,03s user 0,01s system 84% cpu 0,047 total

                                                                                            : 447 мс вообще без кэша zsh и ФС, 65 мс если нужно только проверить, нет ли новых автодополнений и 57 мс, если ничего проверять не нужно. Во всех случаях меньше, если есть системные кэши ФС. Замечу, что корень у меня в RAID1 с ssd и hdd, так что лежащие там файлы (а файлы автодополнения в основном в /usr/share, что в той же ФС) добываются довольно быстро.

                                                                                              0

                                                                                              У меня SSD нет, так что дисковый кеш я оставлю в покое. С ним:


                                                                                              % time zsh -f -i -c 'autoload -Uz compinit ; compinit -D'
                                                                                              0.113 real  0.086 user  0.024 sys  6MB RAM
                                                                                              
                                                                                              % rm -f ~/.zcompdump*
                                                                                              % time zsh -f -i -c 'autoload -Uz compinit ; compinit'
                                                                                              0.167 real  0.132 user  0.029 sys  6MB RAM
                                                                                              % time zsh -f -i -c 'autoload -Uz compinit ; compinit'
                                                                                              0.026 real  0.018 user  0.007 sys  6MB RAM
                                                                                              
                                                                                              % time zsh -f -i -c 'autoload -Uz compinit ; compinit -C'
                                                                                              0.021 real  0.020 user  0.000 sys  6MB RAM

                                                                                              Но ведь кеш compinit можно ещё и откомпилировать, как я упоминал выше!


                                                                                              % zcompile ~/.zcompdump
                                                                                              % time zsh -f -i -c 'autoload -Uz compinit ; compinit'
                                                                                              0.011 real  0.005 user  0.006 sys  6MB RAM
                                                                                              % time zsh -f -i -c 'autoload -Uz compinit ; compinit -C'
                                                                                              0.004 real  0.004 user  0.000 sys  6MB RAM

                                                                                              Вооот! Такие цифры мне нравятся намного больше. Хотя -C в реальной жизни использовать вряд ли получится, вручную за актуальностью следить как-то не хочется.


                                                                                              Update: Размеры:


                                                                                              -rw-r--r-- 1 powerman powerman 40264 апр 25 22:41 .zcompdump
                                                                                              -r--r--r-- 1 powerman powerman 88728 апр 25 22:43 .zcompdump.zwc
                                                                                              0

                                                                                              Оказалось, вышел antigen 2.0, теперь тот же самый конфиг отрабатывает за 180 мс, в начале было около 1000 мс, такая скорость меня полностью устраивает, всем спасибо!

                                                                                  Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                                                                                  Самое читаемое