Обзор Friendly interactive shell (fish) и почему она лучше bash

Недавно админ компании, в которой я работаю, посоветовал попробовать заменить стандартный bash на zsh или fish. Я начал искать информацию по обоим оболочкам, перед тем как попробовать их.

Тут следует пояснить, почему мне не нравится bash. Основное неудобство для меня — это bash script. Когда надо что-то простенькое реализовать, то синтаксис довольно понятен. Но как только тебе надо сделать какую-то сложную логику (хотя бы несколько команд подряд), становится очень сложно разобраться в коде, особенно когда смотришь чужой скрипт. Следующее, что меня расстраивало — это сложности в автокомплите и поиске команд. Конечно, спасало сочетание Ctrl + r, но хотелось, чтобы такой поиск был по умолчанию. Ну и оставалось чисто индивидуальное недовольство настройкой цветов в баше. Единственное, что мне удалось настроить, это подсказка, и то без онлайн генератора PS1 мне было бы очень сложно и это сделать.

Недовольство всеми этими недостатками медленно зрело во мне на протяжении последних 2 лет (приблизительно столько активно пользуюсь командной строкой). Я решил поискать альтернативы. Открыв «Хабр» (основной источник полезной информации для меня) я начал изучать статьи по обоим оболочкам. Первое, что бросилось в глаза — это всего одна короткая статья про fish. Тогда как про zsh было вполне достаточно информации. Изучив поверхностно последнюю оболочку, я понял, что она еще сложнее в усвоении, чем bash. Конечно, все что угодно можно усвоить и использовать по полной программе, но я не сисадмин, а веб-разработчик на Python и мне нужен удобный инструмент, который бы не отвлекал от основной работы, легко и понятно настраивался и конечно же был приятен глазу.

image

Если вас заинтересовала оболочка fish, прошу под кат.

Единственный рускоязычный мануал по fish я нашел тут.

Краткий список плюсов


  • Интерактивный режим работы и дружественность пользователю;
  • Подробная и доступная информация о командах делает их поиск значительно проще, чем в man-страницах оболочки bash. И даже если fish не сможет подключиться к X-серверу, для показа справки будет задействован браузер links;
  • Подсветка синтаксиса: при вводе команды буквы выделяются красным цветом, и меняют его на зелёный, если имя команды написано правильно;
  • Названия существующих папок подчёркиваются;
  • Eсть вкладки и история;
    Достаточно набрать 192 и нажать стрелку вверх как в командной строке будут листаться все когда-либо исполненные команды где фигурировал этот обрывок адреса
    Если начать набирать команду с начала, то сразу же предлагается продолжение из уже когда-либо выполенно команды, стрелочка направо и вся команда готова к запуску. Спасибо avas за подсказку
  • Fish использует специфические конструкции скриптов, которые проще для начинающих пользователей;
  • Автодополнение здесь лучше, чем в bash, так как fish умеет дописывать опции;
  • Легко читаемый вид функций;
  • Легко настраивать в браузере используя команду fish_config.


Это только основные достоинства fish.

Так же хотелось бы написать и про различия между этими двумя оболочками
  • Алиасы заменены и дополнены функциями, что делает fish очень гибкой и легко настраиваемой, в отличие от bash;
  • Файлы конфигурации располагаются в папке .config/fish и разделяются на типы. Например функция, отвечающая за отображение подсказки находится в файле ~/.config/fish/functions/fish_prompt.fish, свои функции можно писать отдельными файлами в папке functions или все в одном файле ~/.config/fish/config.fish (я использую последний вариант, так как проще переносить один файл, например на рабочую машину).


Установка


Ubuntu like дистрибутивы:

sudo apt-get install fish

Перед этим можно добавить ppa для версии 2.1.1(в репе версия 2.0.0):

sudo apt-add-repository ppa:fish-shell/release-2
sudo apt-get update

Я также использую Arch, так что приведу команду и для него:

sudo pacman -S fish


Отличия в подсказках


Меня приятно удивило отображение подсказки в fish. Со скриншота выше видно, что помимо отображения времени в подсказке отображается полный путь к текущей директории, только сокращенный до первых букв. Это чрезвычайно удобно, не надо постоянно вызывать pwd. Также очень приятная особенность состоит в том, что fish можно настроить так, что если в текущей директории есть папка .git, то в подсказке отображается активный branch (committee на скриншоте). Что самое приятное, так настроить подсказку можно всего лишь выбрав в fish_config во вкладке prompt, Classic + git и все. Я лишь добавил к этой функции отображение времени и цвета по своему вкусу.

Полезные ссылки


Оф. сайт
Arch wiki — очень подробно про настройку fish
Рус. ман
config.fish
fish_prompt.fish

Просьба ошибки присылать в личку, постараюсь оперативно исправлять.

Если у вас есть вопросы — задайте в комментариях. С радостью отвечу.
Поделиться публикацией
Комментарии 74
    +5
    Уместнее будет сравнение fish и zsh (zsh+oh-my-zsh). Zsh + oh-my-zsh настраивается очень просто
    С bash сравнивать как то совсем не серьёзно.
      –2
      Ставим
      pacman -S zsh
      curl -L http://install.ohmyz.sh | sh
      

      Выбираем тему темы oh-my-zsh
      Теперь можно сравнивать )
        0
        я никогда не пользовался zsh, поэтому сначала почитал статьи по обеим оболочкам и fish мне показалась легче в освоении. Я сравнивал то, чем я пользовался
          +14
          curl -L install.ohmyz.sh | sh

          Нет уж, спасибо. Выполнять неизвестный скрипт из интернета, да ещё и через http? Так не следует делать никогда!
        +2
        > Это чрезвычайно удобно, не надо постоянно вызывать pwd. Также очень приятная особенность состоит в том, что fish можно настроить так, что если в текущей директории есть папка .git, то в подсказке отображается активный branch (committee на скриншоте).

        В баше это тоже можно сделать при наличии в системе команды, которая выводит значение активного бранча. Нужно просто в PS1 добавить её вызов: $(__git_ps1), или что-то в этом духе (гитом активно не пользуюсь, поэтому не уверен, что эта команда выводит именно текущий бранч, но принцип понятен).
          –4
          видимо, это написано где-то мелким шрифтом или в той части документации, куда я не дочитал, но иметь данную функцию из коробки — приятнее)
          +2
          Простите, но не заметил упоминания САМОГО удобного в fish — а именно работа с историей команд. Сказать «есть история» — явно недостаточно!!!
          Думаю, что в zsh тоже можно настроить так же, но в fish — это просто песня!!!

          Достаточно набрать 192 и нажать стрелку вверх как в командной строке будут листаться все когда-либо исполненные команды где фигурировал этот обрывок адреса
          Если начать набирать команду с начала, то сразу же предлагается продолжение из уже когда-либо выполенно команды, стрелочка направо и вся команда готова к запуску.

          Честно, это все равно что Intellisence — так привыкаешь, что жить без этого больше нельзя.
            0
            Спасибо, действительно, забыл эту функцию описать
              +3
              В bash пробовали history использовать?
              или набирать !192 =))
              Перекрасить под себя терминал bash не составляет труда…
                0
                Не так прочитал. Да, поиск в fish удобнее.
                В bash надо писать — history | grep ____
                  +4
                  Греп не обязательно:
                  ^R
                  PgUp/PgDown
                  А чтобы команды листались по стрелке вверх, достаточно добавить в bashrc:
                  #search in history with arrows
                  bind '"\e[A": history-search-backward' 2>/dev/null
                  bind '"\e[B": history-search-forward' 2>/dev/null
                  
                  –5
                  не могу с вами согласиться, у fish скорее реализована функция реверсивного поиска(Ctrl+r) и тут она работает по умолчанию, что гораздо удобне, чем растягивать пальцы для активации ее в bash. По поводу настройки цвета, то извините, но в bash это совершенно непонятно реализовано, я бы без онлайн генератора никогда бы не настроил. Как видно из названия — это действительно дружественная для пользователя оболочка. Мне, как веб-програмисту, нужен удобный инструмент для работы
                    0
                    В fish отсутствует полноценный аналог Ctrl+r. Их обратный поиск работает иначе, так как он не интерактивный (см.).
              +7
              И чего такого сложного в настройке PS1?
              Заголовок спойлера
              export AA_P="export PVE=\"\\033[m\\033[38;5;2m\"\$(( \`sed -n \"s/MemFree:[\\t ]\\+\\([0-9]\\+\\) kB/\\1/p\" /proc/meminfo\` / 1024 ))\"\\033[38;5;22m/\"\$((\`sed -n \"s/MemTotal:[\\t ]\\+\\([0-9]\\+\\) kB/\\1/p\" /proc/meminfo\`/ 1024 ))MB\"\\t\\033[m\\033[38;5;55m\$(< /proc/loadavg)\\033[m\";echo -en \"\"" \
              export PROMPT_COMMAND="history -a;((\$SECONDS % 10==0 ))&&eval \"\$AA_P\";echo -en \"\$PVE\";" \
              export PS1="\\[\\e[m\\n\\e[1;30m\\][\$\$:\$PPID \\j:\\!\\[\\e[1;30m\\]]\\[\\e[0;36m\\] \\T \\d \\[\\e[1;30m\\][\\[\\e[1;34m\\]\\u@\\H\\[\\e[1;30m\\]:\\[\\e[0;37m\\]\${SSH_TTY} \\[\\e[0;32m\\]+\${SHLVL}\\[\\e[1;30m\\]] \\[\\e[1;37m\\]\\w\\[\\e[0;37m\\] \\n(\$SHLVL:\\!)\\\$ " \
              export PVE="\\033[m\\033[38;5;2m813\\033[38;5;22m/1024MB\\t\\033[m\\033[38;5;55m0.25 0.22 0.18 1/66 26820\\033[m" && eval $AA_P
              

              Ладно, пошутили и хватит. Вот нормальный (цвета по вкусу):
              Заголовок спойлера
              function __prompt_command_generator() {
              	PS1=""
              	PS1+='$(__LAST_EXIT="$?";'        # This needs to be first
              
              	local TXTRED='\[\e[0;31m\]'       # red
              	local TXTGRN='\[\e[0;32m\]'       # green
              	local TXTYLW='\[\e[0;33m\]'       # yellow
              	local TXTBLU='\[\e[0;34m\]'       # blue
              	local TXTPUR='\[\e[0;35m\]'       # purple
              	local TXTCYN='\[\e[0;36m\]'       # cyan
              	local TXTWHT='\[\e[0;37m\]'       # white
              	local BLDRED='\[\e[1;31m\]'       # red    - Bold
              	local BLDGRN='\[\e[1;32m\]'       # green
              	local BLDYLW='\[\e[1;33m\]'       # yellow
              	local BLDBLU='\[\e[1;34m\]'       # blue
              	local BLDPUR='\[\e[1;35m\]'       # purple
              	local BLDCYN='\[\e[1;36m\]'       # cyan
              	local BLDWHT='\[\e[1;37m\]'       # white
              	local TXTRST='\[\e[0m\]'          # Text reset
              
              	#mark root as red
              	PS1+='[[ $UID -eq 0 ]] && echo -n "'$TXTRED'" || echo -n "'$TXTCYN'";'
              	PS1+='echo -n "\u'$TXTRST'";'
              
              	#hide host name if we are on a local machine
              	if [[ -n "$SSH_CLIENT" || -n "$SSH_TTY" ]]; then
              		PS1+='echo -n "@'$TXTYLW'\h'$TXTRST'";'
              	fi
              
              	#append current path
              	PS1+='echo -n " '$BLDBLU'\W";'
              
              	#append git branch
              	if type -p git>/dev/null; then
              		PS1+='__GIT_BRANCH=$(git rev-parse --abbrev-ref HEAD 2> /dev/null);'
              		PS1+='[[ -n "$__GIT_BRANCH" ]] && echo -n "'$TXTBLU'(${__GIT_BRANCH})";'
              		PS1+='unset __GIT_BRANCH;'
              	fi
              
              	#show exit code
              	PS1+='[[ $__LAST_EXIT -eq 0 ]] && echo -n "'$BLDGRN'" || echo -n "'$BLDRED'";';
              	PS1+='unset __LAST_EXIT)'
              
              	PS1+="\\\$ $TXTRST"
              }
              
              #do not use this in e.g. scp
              if [ -z "$SSH_CLIENT" ] || [ -n "$SSH_TTY" ]; then
              	__prompt_command_generator
              fi
              unset __prompt_command_generator
              


                0
                Ветку гита можно же вставить через
                $(__git_ps1)
                , зачем столько сложностей? Есть же функция для этого https://github.com/git/git/blob/master/contrib/completion/git-prompt.sh#L283. Тогда будут показаны состояния гита. Или дело в скорости работы и ненужном функционале?
                  0
                  — функция есть не везде (у меня на андроиде busybox, и хотелось бы, чтобы там этот PS1 тоже работал);
                  — по ссылке — шелл-портянка, у меня всего две строчки, и делают то что надо.

                  <зануда>По скорости. Во многих «стандартных» скриптах используют синтаксис условий [ ] для совместимости. Совмещать приходится для убунты/дебиана из-за велосипеда под названием dash и для всевозможных бсдей. На деле [ является внешней командой, а [[ — внутренней, благодаря этому отрабатывает намного быстрее. Фича есть в баше и busybox, а больше и не надо.</зануда>
                    0
                    Не думаю, что использование [[ вместо [, хоть как-то влияет на производительность. Запустите
                    $ help -m
                    в bash и увидите в списке [, test, echo и другие встроенные команды. Эти builtin-версии предоставляются как раз из-за соображений производительности, так что использовать [[ исключительно с этой целью не стоит, так как особой разницы не будет.
                      +1
                      Баш существо загадочное, соглашусь что это builtin (разница с не-builtin налицо), но и не возьмусь объяснить, почему так происходит:
                      $ time for i in {1..10000}; do [[ "$1" = "123" ]] && echo ok; done
                      real	0m0.061s
                      $ time for i in {1..10000}; do [ "$1" = "123" ] && echo ok; done
                      real	0m0.108s
                      $ time for i in {1..10000}; do /bin/[ "$1" = "123" ] && echo ok; done
                      real	0m10.617s
                      
                        0
                        Да, разница есть. Я предполагал, что небольшая может быть из-за упрощённого разбора строки, но поленился проверить. В man'е есть:
                        Word splitting and pathname expansion are not performed on the words between the [[ and ]];…
                        Может эти дополнительные проходы по содержимому выражения для [ несколько замедляют его.
                          0
                          В zsh примерно то же самое, но хуже:
                          % time ( for i in {1..10000}; do [[ "$1" = "123" ]] && echo ok; done )
                          ( for i in {1..10000}; do; [[ "$1" = "123" ]] && echo ok; done; )  0,01s user 0,00s system 54% cpu 0,018 total
                          % # ^^^^^^ Слишком быстро, нужно увеличить число итераций
                          % time ( for i in {1..1000000}; do [[ "$1" = "123" ]] && echo ok; done )
                          ( for i in {1..1000000}; do; [[ "$1" = "123" ]] && echo ok; done; )  1,48s user 0,01s system 99% cpu 1,500 total
                          % time ( for i in {1..1000000}; do [ "$1" = "123" ] && echo ok; done )
                          ( for i in {1..1000000}; do; [ "$1" = "123" ] && echo ok; done; )  4,13s user 0,64s system 99% cpu 4,785 total
                          % time ( for i in {1..1000000}; do test "$1" = "123" && echo ok; done )
                          ( for i in {1..1000000}; do; test "$1" = "123" && echo ok; done; )  4,43s user 0,33s system 99% cpu 4,767 total
                          


                          : разница в четыре раза. Но работает zsh в целом быстрее: худшее время zsh (сравнивается первая цифра от zsh и real от bash) соответствует лучшему времени bash:
                          # time for i in {1..1000000}; do [ "$1" = "123" ] && echo ok; done
                          
                          real    0m7.674s
                          user    0m7.310s
                          sys     0m0.370s
                          # time for i in {1..1000000}; do [[ "$1" = "123" ]] && echo ok; done
                          
                          real    0m4.187s
                          user    0m4.130s
                          sys     0m0.060s
                          # time for i in {1..1000000}; do test "$1" = "123" && echo ok; done
                          
                          real    0m7.515s
                          user    0m7.240s
                          sys     0m0.280s
                          
                            0
                            Кстати, в fish эти операции медленнее на порядок, хотя вроде test тоже builtin (но вот ни математики, ни {N..M} нету):
                            % time fish -c 'for i in (seq 1000000) ; test "$1" = "123" ; and echo ok ; end'
                            fish -c 'for i in (seq 1000000) ; test "$1" = "123" ; and echo ok ; end'  40,67s user 2,16s system 99% cpu 42,964 total
                            % time fish -c "set s (seq 1000000)"
                            fish -c "set s (seq 1000000)"  3,25s user 0,26s system 97% cpu 3,616 total
                            
                            .

                            Замечу, что time ( for i in {1..1000000}; do /usr/bin/\[ "$1" = "123" \] && echo ok; done ), запущенная в zsh во время написания предыдущего комментария, до сих пор не завершилась.
                              0
                              Не думал, что в фише такой чудной синтаксис. Т.е. обратная совместимость напрочь отсутствует. Медленнее может быть из-за seq (внешняя команда).

                              dash быстр, но он требует дедовских методов программирования на шелле, так как по возможностям уступает даже busybox. И тут даже видно, как его обгоняет zsh:

                              $ time busybox sh  -c 'for i in $(seq 1000000); do [[ "$1" = "123" ]] && echo ok; done'
                              real	0m3.783s
                              $ time busybox sh  -c 'for i in $(seq 1000000); do [ "$1" = "123" ] && echo ok; done'
                              real	0m3.719s
                              $ time sh  -c 'for i in {1..1000000}; do [[ "$1" = "123" ]] && echo ok; done'
                              real	0m6.310s
                              $ time sh  -c 'for i in {1..1000000}; do [ "$1" = "123" ] && echo ok; done'
                              real	0m10.340s
                              $ time dash  -c 'for i in $(seq 1000000); do [ "$1" = "123" ] && echo ok; done'
                              real	0m2.394s
                              $ time zsh  -c 'for i in {1..1000000}; do [ "$1" = "123" ] && echo ok; done'
                              real	0m5.541s
                              $ time zsh  -c 'for i in {1..1000000}; do [[ "$1" = "123" ]] && echo ok; done'
                              real	0m1.975s
                              

                                0
                                Медленнее может быть из-за seq (внешняя команда).
                                Я специально сделал отдельной строкой time fish -c "set s (seq 1000000)": именно затем, чтобы вы не считали, что здесь виноват seq.
                                  0
                                  При использовании seq ksh быстрее всех:
                                  % for sh in bb posh dash zsh bash mksh ksh ; do eval time $sh -c '''for i in $(seq 1000000); do test "$1" = "123" && echo ok ; done''' ; done
                                  bb -c 'for i in $(seq 1000000); do test "$1" = "123" && echo ok ; done'  2,80s user 0,17s system 105% cpu 2,818 total
                                  posh -c 'for i in $(seq 1000000); do test "$1" = "123" && echo ok ; done'  2,51s user 0,19s system 100% cpu 2,689 total
                                  dash -c 'for i in $(seq 1000000); do test "$1" = "123" && echo ok ; done'  1,39s user 0,09s system 100% cpu 1,470 total
                                  zsh -c 'for i in $(seq 1000000); do test "$1" = "123" && echo ok ; done'  11,39s user 0,64s system 100% cpu 12,020 total
                                  bash -c 'for i in $(seq 1000000); do test "$1" = "123" && echo ok ; done'  6,87s user 0,28s system 100% cpu 7,144 total
                                  mksh -c 'for i in $(seq 1000000); do test "$1" = "123" && echo ok ; done'  2,40s user 0,01s system 100% cpu 2,403 total
                                  ksh -c 'for i in $(seq 1000000); do test "$1" = "123" && echo ok ; done'  1,02s user 0,07s system 99% cpu 1,092 total
                                  


                                  При использовании {N..M} ksh почему‐то медленнее, но всё равно быстрее всех:
                                  % for sh in ksh zsh bash ; do eval time $sh -c '''for i in {1..1000000}; do test "$1" = "123" && echo ok ; done'''; done
                                  ksh -c 'for i in {1..1000000}; do test "$1" = "123" && echo ok ; done'  2,53s user 0,08s system 99% cpu 2,621 total
                                  zsh -c 'for i in {1..1000000}; do test "$1" = "123" && echo ok ; done'  4,20s user 0,38s system 99% cpu 4,589 total
                                  bash -c 'for i in {1..1000000}; do test "$1" = "123" && echo ok ; done'  6,42s user 0,42s system 99% cpu 6,850 total
                                  
                                  , тогда как остальные быстрее, чем с seq.

                                  А вот с {N..M} и [[ ]] у всех выигрывает zsh:
                                  for sh in ksh zsh bash ; do eval time $sh -c '''for i in {1..1000000}; do [[ "$1" = "123" ]] && echo ok ; done'''; done
                                  ksh -c 'for i in {1..1000000}; do [[ "$1" = "123" ]] && echo ok ; done'  1,95s user 0,14s system 99% cpu 2,104 total
                                  zsh -c 'for i in {1..1000000}; do [[ "$1" = "123" ]] && echo ok ; done'  1,47s user 0,03s system 99% cpu 1,510 total
                                  bash -c 'for i in {1..1000000}; do [[ "$1" = "123" ]] && echo ok ; done'  3,78s user 0,08s system 99% cpu 3,866 total
                                  
                                  А ksh всё равно, test там или [[ ]].

                                  Ну и последний вариант, где ksh всех бьёт: seq и [[ ]]:
                                  % for sh in mksh ksh zsh bash ; do eval time $sh -c '''for i in $(seq 1000000); do [[ "$1" = "123" ]] && echo ok ; done'''; done
                                  mksh -c 'for i in $(seq 1000000); do [[ "$1" = "123" ]] && echo ok ; done'  1,47s user 0,02s system 100% cpu 1,481 total
                                  ksh -c 'for i in $(seq 1000000); do [[ "$1" = "123" ]] && echo ok ; done'  0,69s user 0,05s system 97% cpu 0,759 total
                                  zsh -c 'for i in $(seq 1000000); do [[ "$1" = "123" ]] && echo ok ; done'  8,89s user 0,16s system 100% cpu 9,041 total
                                  bash -c 'for i in $(seq 1000000); do [[ "$1" = "123" ]] && echo ok ; done'  4,25s user 0,10s system 100% cpu 4,343 total
                                  


                                  Если что, то bb — это то же самое, что busybox ash. (Кстати, у busybox есть и другой вариант оболочки — hush. Последний раз, когда я её пробовал, она валилась при попытке совместного использования с powerline. Я не знаю, есть ли hush в релизе, но у меня в системном busybox её нет точно.)
                                    0
                                    [ ] у меня работает стабильно не быстрее во всех оболочках. Впрочем, я не люблю и предпочитаю не использовать ни [[ ]], ни [ ].
                                    % for sh in bb posh dash zsh bash mksh ksh ; do eval time $sh -c '''for i in $(seq 1000000); do [ "$1" = "123" ] && echo ok ; done''' ; done
                                    bb -c 'for i in $(seq 1000000); do [ "$1" = "123" ] && echo ok ; done'  2,85s user 0,23s system 104% cpu 2,942 total
                                    posh -c 'for i in $(seq 1000000); do [ "$1" = "123" ] && echo ok ; done'  2,69s user 0,10s system 100% cpu 2,782 total
                                    dash -c 'for i in $(seq 1000000); do [ "$1" = "123" ] && echo ok ; done'  1,76s user 0,05s system 100% cpu 1,807 total
                                    zsh -c 'for i in $(seq 1000000); do [ "$1" = "123" ] && echo ok ; done'  11,66s user 0,60s system 100% cpu 12,244 total
                                    bash -c 'for i in $(seq 1000000); do [ "$1" = "123" ] && echo ok ; done'  7,02s user 0,53s system 100% cpu 7,539 total
                                    mksh -c 'for i in $(seq 1000000); do [ "$1" = "123" ] && echo ok ; done'  3,12s user 0,06s system 100% cpu 3,174 total
                                    ksh -c 'for i in $(seq 1000000); do [ "$1" = "123" ] && echo ok ; done'  1,05s user 0,05s system 99% cpu 1,105 total
                                    0
                                    Ну и там не просто чудо‐синтаксис. В fish нет встроенной математики (кроме test с -eq и пр., но на этом далеко не уедешь) (math использует bc), поэтому я даже не пытался сконструировать что‐то вроде for (( I=0; I < 1000000; I++ )).

                                    Кстати, чудо‐синтаксис zsh:
                                    zsh -c '() for i { [[ "$1" = "123" ]] && echo ok } $(seq 10)'  0,00s user 0,00s system 0% cpu 0,010 total
                                    zsh -c '() for i { [[ "$1" = "123" ]] && echo ok } $(seq 100)'  0,00s user 0,00s system 0% cpu 0,013 total
                                    zsh -c '() for i { [[ "$1" = "123" ]] && echo ok } $(seq 1000)'  0,00s user 0,00s system 0% cpu 0,011 total
                                    zsh -c '() for i { [[ "$1" = "123" ]] && echo ok } $(seq 10000)'  0,14s user 0,00s system 94% cpu 0,149 total
                                    zsh -c '() for i { [[ "$1" = "123" ]] && echo ok } $(seq 100000)'  10,96s user 0,02s system 99% cpu 10,985 total
                                    zsh -c '() for i { [[ "$1" = "123" ]] && echo ok } $(seq 125000)'  21,10s user 0,04s system 99% cpu 21,164 total
                                    zsh -c '() for i { [[ "$1" = "123" ]] && echo ok } $(seq 150000)'  32,82s user 0,02s system 100% cpu 32,831 total
                                    zsh -c '() for i { [[ "$1" = "123" ]] && echo ok } $(seq 175000)'  43,93s user 0,16s system 99% cpu 44,128 total
                                    zsh -c '() for i { [[ "$1" = "123" ]] && echo ok } $(seq 200000)'  70,21s user 0,14s system 100% cpu 1:10,35 total
                                    


                                    Где‐то в обработке функций (чудо‐синтаксис представляет из себя анонимную функцию с одной командой (циклом for, записанным в сокращённой форме) и аргументами) явно забыли что‐то плохое.
                      +2
                      Фиш клёвый, сам юзаю. Поиск по истории потрясный. Но у него есть одна «фича» — несовместимость синтаксиса с bash. Поэтому никогда не ставьте его на сервера! И ещё он очень медленно запускается, если в конфие много алиасов, никак не починят эту фигню :(

                      Оставлю это здесь: oh-my-fish
                        0
                        Лучшее — враг хорошего…
                          +13
                          Что ж Вы за разработчик, если за 2 года не смогли ознакомиться документацией (коей уйма) по, якобы, нужному Вам инструменту и настроить bash под свои нужды? Если Вы web-разработчик на python, какая Вам принципиальная разница — bash у Вас, fish, zsh или вообще korn shell?
                          Из приведённых аргументов ни одного стоящего не нашёл. Все или «на любителя», или просто от незнания bash. И перебор истории по подстроке с помощью стрелочек есть, и регистронезависимая подстановка по табу, и перестановка местами набранных уже слов и букв, и перевод набранного слова в верхний или нижний регистр, и, вообще, много чего есть, только читать документацию надо. Да и google, обычно, доступен всем.

                          PS. «Оболочка» — женского рода, значит, должно быть «по обеим», а не «по обоим».
                            –3
                            именно потому, что я веб-разработчик, а не сис-админ, я попробовал заменить неудобный инструмент на удобный мне и посоветовать это сделать тем, кто так же как и я нуждается в дружелюбном и легконастраиваемом инструменте. Если есть выбор — то зачем мучиться?
                              +7
                              Никогда не понимал этой аргументации. «Я…, а не сисадмин!» Вы действительно представляете нас такими заросшими щетиной (бриться некогда, надо bash осваивать!), толстых (гулять некогда, надо bash осваивать!), грязных (мыться ...) людей, которые специально выбирают максимально неудобный для себя инструмент?

                              Пока что Ваша статья, как Вам уже писали, похожа только на «не понял, документацию не открыл, взял что попроще, чтоб сразу за меня думало».
                                +4
                                я никого не хотел обидеть, я знаю несколько сис-админов и они чудесные люди. мне не платят деньги за знание баша, мне платят за рабочий код на питоне. это всего лишь вопрос целесообразности. Я не спец в баше, но знаю его на достаточном уровне, чтобы делать свою работу. Но я нашел для себя более удобный инструмент, который позволяет секономить мое время и нервы и хотел поделиться им с сообществом, так как на хабре только единственная статья про него
                            +4
                            Даешь zsh!
                              +3
                              Искал список минусов, как то не логично, если есть списоко плюсов. Прочитав заголовок, конце ожидал сводную табличку со сравнениями.
                              • НЛО прилетело и опубликовало эту надпись здесь
                                  –2
                                  Ретроградство какое-то. Где в реальной ситауции невозможно поставить bash?
                                  • НЛО прилетело и опубликовало эту надпись здесь
                                      0
                                      Ну вам нужно, вы и пишите, остальные то тут причём. У меня стоит интерпретатор ruby, например, хотя я на нём и не пишу, а только какие-то программы запускаю. Не мешает как-то.
                                      • НЛО прилетело и опубликовало эту надпись здесь
                                          +3
                                          Если я в C++ boost буду использовать, то что? бустизм?
                                          • НЛО прилетело и опубликовало эту надпись здесь
                                    0
                                    Скрипты нужно писать под sh, чтобы ими можно было пользоватся не зависимо от наличия баша.


                                    Это если ультра-отчуждаемые. pure sh — это все-таки реальный хардкор. Или приходится делать меньше sh, больше awk.
                                      0
                                      POSIX sh (это так называется) — вполне ок, если не заморачиваться на написание всей логики без форков во внешние бинарники.
                                      POSIX sh все-таки рассчитан на использование вместе с coreutils, так что тут проблемы нет. Просто не надо на нем писать сильно сложные вещи.
                                      0
                                      Можно писать скрипты и на bash, он вполне себе даже на embedded работает. Но при этом стоит указывать в she-bang именно bash: #!/bin/bash. Если пишете #!/bin/sh и используете башизмы, то на системе, отличной от вашей, может всё слететь к чёрту. В Ubuntu/Debian, например:
                                      $ ls -l /bin/sh
                                      lrwxrwxrwx 1 root root 4 Nov  8 19:49 /bin/sh -> dash
                                      
                                        0
                                        Кажется, dash — это самая ограниченная из POSIX‐совместимых оболочек. Именно от неё я узнал, что ${var//pat/repl} в POSIX нету: среди busybox ash, ksh, mksh, bash, zsh она единственная кажет Bad substitution на эту конструкцию. Также она единственная, кто не поддерживает $RANDOM.
                                          0
                                          Есть еще posh.

                                          $ posh
                                          $ echo $RANDOM
                                          
                                          $ foo=azzzazz
                                          $ echo ${foo//z/}
                                          posh: ${foo//z/}: bad substitution
                                          

                                    • НЛО прилетело и опубликовало эту надпись здесь
                                        +9
                                        1. Вот он всем хорош, кроме несовместимости синтаксиса в командах.

                                        sudo apt-get update && sudo apt-get upgrade -y

                                        уже не выполнишь, надо писать

                                        sudo apt-get update; and sudo apt-get upgrade -y

                                        2. Также приходится экранировать некоторые символы типа '*', '&'

                                        например:

                                        sudo apt-get remove libreoffice\*

                                        Особенно раздражает в регулярках grep

                                        3. Еще возникают проблемы при переносе конфигурации с одного компа на другой.
                                        Перед каждой строкой пишет ошибку типа «set_color is not defined»
                                        Лечится запуском fish_config и переключением prompt туда-сюда.

                                        4. Мне не нравится, как во многих поставляемых prompt сокращает путь, например /v/l/nginx это /var/log/nginx
                                        Приходится ручками подправлять.

                                        В общем — очень «кавайный» шелл, удобный. Расцветка, автодополнение и хистори — вот ключевые фичи, из-за которых его стоит хотя бы глянуть.
                                          0
                                          1. Синтаксис мне тоже не нравиться. Но это не самая большая проблема.
                                          2. В bash и zsh тоже можно настроить всё так, чтобы нужно было экранировать. И лучше так и сделать: иначе вам всегда нужно помнить, что находится в текущем каталоге.

                                          Я его смотрел, но fish слишком ограничен. Часто хочу какую-нибудь возможность из zsh, ан нет её. Даже нельзя сделать $COMMAND args, нужен eval или env. Хотя fish красивый.
                                          +7
                                          Увидев о чем статья я попробовал вспомнить когда же я впервые о нем прочитал, что вот это будет такая модная замена башу и конкурент zsh`у. Я такие вещи вспоминаю по месту где я сидел когда пробовал, вышло, что пробовал я оный fish на работе с которой уволился в начале 2005 года. То есть пробовал я до начала 2005 года, получается больше 10 лет назад.
                                          За прошедшее время я успел сменить 6 городов жительства, четыре цвета волос, жениться, вырастить чужого ребенка и развестись, а fish так и позиционируется как «будущая замена и будущий конкурент». Сдается мне, что если за 10 лет он так и остался шеллом для трех фриков, то и останется таковым навсегда, увы и ах.
                                          Лучше настройте под себя bash или zsh, чем мучаться с шеллом о котором никто не знает и ошибки в котором придется ловить самому и только самому, ведь его никто больше не использует.
                                            0
                                            Около месяца назад перешел на fish.
                                            Понравилось:
                                            1. История команд — действительно удобно. Пишем vim, жмякаем Ctrl+p и находим в истории соседнюю команду с vim
                                            2. Подсветка — не сказать что уж очень удобно, но лучше, чем ее отсутствие (подсвечиваются не только команды и ключи к ним, но и узлы файловой системы)

                                            Не понравилось:
                                            1. Странная интерактивность при переходе по ФС — имеем каталог ~/.vim/bundle/vim_lib/ в котором у нас каталог .vimprj. Перейдя в первый каталог пытаюсь перейти во второй `cd .vimp` жмякаю Tab, fish мне предлагает перейти в ~/.vimprojects_tabs, зачем? И так постоянно
                                            2. Не находит некоторые ключи утилит, подсвечивая их красным, от чего все равно приходится лезть в man и освежать память
                                            3. Странный, несовместимый синтаксис. Возможно кому то он понятнее, но; and и; or это что то изотерическое и совершенно несовместимое. Я пишу на большом числе языков, не очень хочется изучать еще и диалекты
                                              0
                                              Еще есть жуткий «косяк» с переходами (правда разработчики говорят, что это фича) – при переходе в директорию-симлинк переход осуществляется в директорию источника симлинка. И это никак не исправить.
                                                0
                                                Разработчики явно говорят, что оболочка не должна быть настраиваемой: в zsh вы можете иметь эту возможность, а можете не иметь. В fish вы либо будете иметь её всегда, либо не будете иметь никогда, но чего точно не будет, так это настройки CHASE_LINKS.
                                              –1
                                              Спасибо за напоминание о том, что пора спрыгивать с bash :)
                                                –1
                                                ааа, это был сарказм. чесслово
                                                +2
                                                Я себе в Zsh настроил подсветку, как в Fish. Делается очень просто:

                                                Плюс, поставил себе Pure, поставил для iTerm2 тему Seti UI и поменял цвета для некоторых штук.
                                                  0
                                                  Zsh-syntax-highlighting довольно нетороплив (очень заметно, если вам зачем‐то нужно использовать echo long-pasted-string | …) и дюже неточен. Если вы найдёте описание грамматики zsh для pygments, то можно использовать bitbucket.org/ZyX_I/zsh-pygments-highlighting вместе с bitbucket.org/ZyX_I/zpython. Работает намного быстрее, но без грамматики будет работать только пока вы пишете bash‐совместимые команды.
                                                  +1
                                                  Судя по статье, ни bash, ни zsh, ни fish хотя бы на уровне документации вы не осилили. Есть основания полагать, что программируете вы точно так же.
                                                    0
                                                    Ваш комментарий представляет для мня Вещь, которую нельзя обойти стороной, не отреагрировав, но и отреагировать непозволительно. Всё что остается сделать — это описать эту диллему в ответе на комментарий.
                                                      +1
                                                      Я бы не ставил вас перед этой дилеммой, если бы в статье были бы хоть какие-то примеры, где fish работает лучше, чем bash или zsh. Но нет, вместо них смешные безграмотные утверждения про алиасы-функции. А про конфигурационные файлы и дополнение команд и опций даже смешно не получилось — просто откровенная демонстрация полного незнания предмета, которое и помешало написать интересную статью. Впрочем, мы квиты. Читая вашу статью я тоже мучался дилеммой: то ли вы так эникейщиков троллите, то ли вы бредите. А оказалось, что закон По применим не только к фундаментализму.
                                                        –2
                                                        К сожалению слепому не объяснишь, как выглядит зеленый цвет.
                                                          +2
                                                          Что может говорить хромой об искусстве Герберта фон Караяна? Если ему сразу заявить, что он хромой, он признает себя побеждённым. О чём может спорить человек, который не поменял паспорт? Какие взгляды на архитектуру может высказать мужчина без прописки? Пойманный с поличным, он сознается и признает себя побеждённым. И вообще, разве нас может интересовать мнение человека лысого, с таким носом? Пусть сначала исправит нос, отрастит волосы, а потом и выскажется.

                                                          — М. М. Жванецкий.
                                                            –2
                                                            я вижу у вас такие объемные статьи, где все подробно расписано и вся документация приведена, все как и должно быть, прям образцовые статьи. Ой что это? а где же эти статьи?
                                                              +1
                                                              Reductio ad hominem, второй раз уже. Дело в том, что отсутствие у меня писательского таланта и, главное, желания писать статьи, никаким образом не делает вашу статью лучше, а владение предметом более глубоким.
                                                                0
                                                                в следующих статьях учту ваши пожелания
                                                          0
                                                          это не моя статья. более того, я согласен с вашими комментариями. хотябы потому, что знаю лично автора и его скилл. просто вами было забавно подмечено, а мне — не красиво поддакивать (обидеть человека не хочется) и выгораживать — лгать себе. Вот и осталось одно — подметить диллему ;) удачи
                                                            0
                                                            Я был лучшего мнения о вас. К сожалению, я склонен переоценивать людей
                                                              0
                                                              Теперь мы квиты, касательно мнений ;)
                                                      0
                                                      Использую fish уже около четырех лет, и основная причина — поставил и забыл, не надо ковыряться в конфигурациях, ибо предустановки уже достаточно хороши для повседневных нужд. Поддержка Mac OS X является также немаловажным фактором, т.к. это основная операционная система для работы в моем случае.

                                                      Что касается скриптов, то я явлюсь сильным сторонником мнения, что программы должны писаться для человека, а не машины. Поэтому bash вообще не использую, все скрипты пишу на Python. У этого подхода есть и плюсы и минусы, но в долгосрочной перспективе (например, сборочные скрипты для Jenkins) это себя оправдывает, как минимум в моем случае. Если же нужно запустить bash-однострочник, ничто не мешает запустить bash напрямую и выполнить в нем команду.

                                                      Так что не волнуйтесь насчет RTFM-комментариев. У каждого человека своя уникальная ситуация — когда маленькие дети не дают нормально выспаться и работы невпроворот, уже не до чтения мануалов и настройки конфигураций, надо чтобы работало здесь и сейчас, и можно было сосредоточиться на своих основных обязанностях, как например, веб-разработка в вашем случае.
                                                        0
                                                        Большое спасибо за поддержку, именно это имелось ввиду. Сейчас просто громадное количество информации нужно пропустить через себя, а ведь люди не идеальны, часто уже путаешься даже в сочетаниях клавиш.
                                                        +1
                                                        «Обзор» от человека, который ничего не знает ни про сабж, ни про то, с чем его сравнивает. Такое в блог себе пишут, а не на технический ресурс.

                                                        Я просто оставлю это здесь: wiki.bash-hackers.org
                                                          +1
                                                          Мне кажется, что питон это самый адекватный скриптовый язык, соответственно нужен шелл в котором питон язык автоматизации, понятное дело с некоторыми дополнительными либами для упрощения типовых задач.
                                                            +1
                                                              0
                                                              Интересно, спасибо за наводку, я как-то гуглил неправильно — этот вариант не попадался

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

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