LINUX.ORG.RU

Переезжаем на Fish

 , ,

Переезжаем на Fish

4

3

Fish — это современный командный интерпретатор, недавно переписанный на Rust, который не требует особой настройки, поддерживая из коробки автодополнение и подсветку синтаксиса. Является лучшим Unix SHELL по версии Slant.

Установка

Установка Fish:

# Arch Linux, Manjaro и тп 
sudo pacman -S fish

# Fedora
sudo dnf install fish

# NixOS
nix-env -i fish

# Ubuntu и остальные Debian-based
sudo add-apt-repository ppa:fish-shell/release-4
sudo apt update
sudo apt install fish

Чтобы сделать fish оболочкой по умолчанию для текущего пользователя:

sudo chsh -s $(which fish) $(whoami)

Прочитайте справку после запуска fish:

help

Fisher — это менеджер плагинов для Fish:

# Из стандартного репозитория Arch
pacman -S fisher

# Вручную
curl -sL https://raw.githubusercontent.com/jorgebucaran/fisher/main/functions/fisher.fish | source && fisher install jorgebucaran/fisher

Конфигурация Fish

Основная конфигурация хранится в ~/.config/fish/config.fish:

if not status is-interactive
  exit
end

# Эти пути будут добавлены в $PATH единожды
fish_add_path -m ~/bin ~/.local/bin

# Определим переменные XDG
set -q XDG_DATA_HOME || set -U XDG_DATA_HOME $HOME/.local/share
set -q XDG_STATE_HOME || set -U XDG_STATE_HOME $HOME/.local/state
set -q XDG_CONFIG_HOME || set -U XDG_CONFIG_HOME $HOME/.config
set -q XDG_CACHE_HOME || set -U XDG_CACHE_HOME $HOME/.cache

# Различные настройки
# Используем привычные сочетания клавиш
set -U fish_key_bindings fish_default_key_bindings

# Двойное нажатие ESC не работает, если выставить меньше
set -g fish_escape_delay_ms 300

# В Yakuake вывод fetch не очень смотрится
if command -q fastfetch && ! string match -q -- "*yakuake*" (pstree -s -p $fish_pid)
  fastfetch
end

Настроить fish можно через веб-интерфейс:

fish_config

Отличия Fish от Bash и ZSH

Другой синтаксис

  • Нет $$ и прочих $*.
  • Не нужно экранировать переменные.
  • Нет HEREDOC.
  • Он напоминает Ruby с его end для обозначения окончания блока вместо fi, done, esac и тп.
  • Вместо $(command) нужно писать просто (command).
  • Кроме алиасов есть аббревиатуры, которые при вводе заменяются на полную команду.

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

Переменные окружения

Fish использует собственный механизм управления переменными окружения, который отличается от bash и zsh. Основные типы переменных:

  • set VAR value — устанавливает переменную VAR только в текущей сессии.
  • set -x VAR value — делает переменную доступной для дочерних процессов (аналог export в bash).
  • set -gx VAR value — глобальная переменная, доступная во всех сессиях fish.
  • set -Ux VAR value — универсальная переменная, которая сохраняется в ~/.config/fish/fish_variables, те эту команду достаточно ввести в терминале один раз.
  • set -e VAR — удаляет переменную.

Пример установки переменных:

set -x PATH /usr/local/bin $PATH  # Добавляем путь в переменную окружения
set -Ux EDITOR vim                # Устанавливаем универсальную переменную

Для модификации $PATH есть функция fish_path_add:

fish_add_path $HOME/bin $HOME/.local/bin

Это аналогично установке универсальных переменных:

set -U fish_user_paths $HOME/bin $HOME/.local/bin

Темы и плагины

Темы можно ставить как через fisher так и Oh my fish.

Oh my fish содержит ряд адаптированных тем из мегапопулярного Oh my zsh, а так же дополнительно позволяет ставить плагины:

По всей видимости, oh my fish сломан и его лучше не использовать

curl -L https://get.oh-my.fish | fish

Поиск тем или пакетов:

omf search [ -t | -p ] name

Список тем:

omf theme

Установка темы:

omf install pure

Смена ее на дефолтную:

omf theme default

Через fisher так же можно ставить темы:

fisher install pure-fish/pure

Работа с плагинами через fisher:

fisher install plugin_name
fisher remove plugin_name
fisher list

Редактирование списка установленных плагинов:

$EDITOR $__fish_config_dir/fish_plugins

Пример плагинов для установки:

Gazorby/fish-abbreviation-tips
PatrickF1/fzf.fish
jethrokuan/z
jorgebucaran/autopair.fish
jorgebucaran/replay.fish
nickeb96/puffer-fish

Популярные плагины, которые можно поставить:

  • Gazorby/fish-abbreviation-tips: показывает подсказки для аббревиатур, помогая запомнить их.

  • PatrickF1/fzf.fish: интеграция fzf для удобного поиска файлов, истории команд и Git-веток.

  • acomagu/fish-async-prompt: асинхронно обновляет промпт. Бажный.

  • franciscolourenco/done: показывает десктопные уведомления о завершении длительных команд.

  • jethrokuan/z: быстрый переход по каталогам с использованием z.

  • jorgebucaran/autopair.fish: автоматическое закрытие скобок.

  • jorgebucaran/replay.fish: позволяет запускать команды Bash (replay ...).

  • joseluisq/gitnow@2.12.0: содержит функции для работы с git.

  • nickeb96/puffer-fish: добавляет привычный многим !! для быстрой подстановки предыдущей команды.

После редактирования списка запускаем обновление плагинов:

fisher update

При установке через fisher install плагины добавляются в тот список в файле, remove — удаляются. Если что-то удалить из него, то при вызове update будут удалены соответствующие плагины.

Ряд плагинов можно поставить через OMF:

omf update  # Обновим Oh my fish
omf install pyenv

Но лучше это делать через fisher:

fisher install oh-my-fish/plugin-<name>

Например:

fisher install oh-my-fish/plugin-pyenv

Прочее

Для работы с буфером обмена есть готовые функции fish_clipboard_copy и fish_clipboard_paste.

Автодополнения генерируются прямо из man-файлов:

fish_update_completions

Алиасы можно сохранять прямо из терминала с помощью флага -s:

# Заменим убогий ls на модный ROR-аналог
alias -s ls "eza --icons"

Добавляем sudo к текущей либо предыдущей команде:

function repeat_with_sudo
    # Получаем текущую команду из командной строки
    set -l cmd (commandline)
    
    # Если команда пустая, берём последнюю команду из истории
    if test -z "$cmd"
        set cmd $history[1]
    end
    
    # Заменяем текущую команду на "sudo <команда>"
    commandline -r "sudo $cmd"
end

funcsave repeat_with_sudo

# Это нужно добавить в конфиг
# Привязка к Alt+S
bind \es 'repeat_with_sudo'

# Готовый плагин для oh my fish
fisher install oh-my-fish/plugin-sudope

Переопределяем command not found:

function fish_command_not_found
  # Вместо этой строки нужно какую-то логику реализовать
  __fish_default_command_not_found_handler $argv[1]
end

funcsave fish_command_not_found

В арче, если установлен pkgfile, то все работает из коробки:

~
❯ python2
python2 may be found in the following packages:
  archlinuxcn/python2 2.7.18-12 /usr/bin/python2

Менеджер сниппетов Pet можно интегрировать с fish через плагин otms61/fish-pet:

fisher install otms61/fish-pet

Добавляем сочетание клавиш:

# Сочетания должны храниться в функции
function fish_user_key_bindings
  bind \cs 'pet-select'
end

# Сохраняем сочетания
funcsave fish_user_key_bindings

# Если сочетания заданы, то отредактируйте ф-ию
funced fish_user_key_bindings

Добавление аббревиатур:

abbr -a vimrc 'vim ~/.vim/vimrc'
abbr > ~/.config/fish/conf.d/abbrs.fish

Аббревиатуры заменяются на полные команды.

Заключение

Fish — простой шеллозаменитель для тех, кому лень заморачиваться с настройкой zsh. Он существует достаточно давно, но его фанатская база не является какой-то огромной, пользователи часто пользуются дефолтом, редко меняя шелл.

Что радует:

  • работает заметно быстрее того же zsh;
  • минимум настроек;
  • чистые конфиги;
  • более дружелюбный синтаксис и предсказуемое поведение с попыткой сохранить совместимость в отличии от какого-нибудь марсианского nushell.

Что огорчает:

  • мало плагинов;
  • странные баги, которые вылечить можно только сносом ~/.config/fish;
  • нестандартный синтаксис не позволяет копипастить команды без использования того же replay + нужно переучиваться.

Вердикт: стоит попробовать.

Полезные ресурсы

Дополнительные плагины и информация:

Полезные статьи про fish:

★★★

Проверено: dataman ()
Последнее исправление: rtxtxtrx (всего исправлений: 30)
# Определим переменные XDG
set -q XDG_DATA_HOME || set -U XDG_DATA_HOME $HOME/.local/share
set -q XDG_STATE_HOME || set -U XDG_STATE_HOME $HOME/.local/state
set -q XDG_CONFIG_HOME || set -U XDG_CONFIG_HOME $HOME/.config
set -q XDG_CACHE_HOME || set -U XDG_CACHE_HOME $HOME/.cache

Объясни кстати, если не сложно, пожалуйста, простым языком смысл вот этих вот XDG_ переменных. Все их советуют использовать, но я не вдупляю зачем.

ivan007007
()
Ответ на: комментарий от Lrrr

статья написана мной. напиши свою нейронкой я хоть поржу с нее.

rtxtxtrx ★★★
() автор топика
Ответ на: комментарий от ivan007007

переменная установлена (ложь/истина) || (или срабатывает, если ложь, те не установлена) устанавливаем переменную

rtxtxtrx ★★★
() автор топика

И в чём практический смысл вот этого?

if not status is-interactive
  exit
end

Я тебя правильно понял, что ты подразумеваешь, что ты не предполагаешь использование fish в качестве login шелла, то есть он запускается из какого-то другого, в качестве sub-шелла. И если так случилось, что обращение к нему произвелось не-интерактивно, то должен быть произведен выход обратно в родительский шелл?

ivan007007
()
Ответ на: комментарий от rtxtxtrx

Это я всё понимаю. Но вопрос был не «что это такое?», а «зачем?»

ivan007007
()

Хорошая статься, спасибо!

nuxster ★★★
()
Ответ на: комментарий от gagarin0

Я вот тут нашел первой ссылкой в гуле TUI написанный на pure bash.

На bash можно много чего написать.

https://github.com/Crestwave/shmenu

Да, эта программа является TUI.

это меня поставило в окончательный тупик.

Что не так?

monk ★★★★★
()
Ответ на: комментарий от gagarin0

вопрос был в том является ли bash TUI или нет.

вы можете сами себе ответить на этот вопрос. Для этого понадобятся два простых шага - 1. расшифруйте аббревиатуру TUI 2. дайте определение bash.

FishHook
()
Ответ на: комментарий от gagarin0

для себя я все давно определил

мне кажется, вы неправильно определили. Допустим, у вас есть баш скрипт, который автоматически по крону стартует и удаляет файлы в директории. Где здесь вообще юзер интерфейс?

FishHook
()
Ответ на: комментарий от gagarin0

еще раз, где?

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

FishHook
()
Ответ на: комментарий от gagarin0

Где здесь вообще user interface ?

сами себе и ответьте на этот вопрос, это же вы считаете, что баш это интерфейс. А вам говорят, что баш это много что, и это командный интерпретатор в первую очередь, и откуда баш получает команду для интерпретации - из REPL от пользователя или из /dev/urandom это конкретный частный сценарий его использования. Не понятно?

FishHook
()
Ответ на: комментарий от gagarin0

не входит. это шелл. он запускается терминалом или эмулятором терминала. tui уже шеллом запускается.

telnet doom.w-graj.net 666
rtxtxtrx ★★★
() автор топика
Последнее исправление: rtxtxtrx (всего исправлений: 1)
Ответ на: комментарий от gagarin0

Terminal User Interface

Text User Interface

входит в категорию

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

FishHook
()
Ответ на: комментарий от gagarin0

My internet was down for over a week and I had Writing a TUI in Bash cloned.

Пишем туи на баш… Как из этого следует, что баш туи? Ты магистр логики какой-то

rtxtxtrx ★★★
() автор топика
Ответ на: комментарий от rtxtxtrx

Пишем туи на баш…

Bash не входит в TUI

Ты магистр логики какой-то

ты тоже не плох

gagarin0
()
Ответ на: комментарий от FishHook

я же просил меньше слов.

никто никогда не определял эту категорию.

В этом смысле баш никогда не позиционировался как TUI.

давайте я вас лично спрошу, для вас и для многих других похожих на вас, bash входит в категорию «TUI» программ или нет?

gagarin0
()
Ответ на: комментарий от gagarin0

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

FishHook
()
Ответ на: комментарий от gagarin0

Тогда bash (с помощью tkbash, аналогичная штука и для gtk имеется) и GUI тоже является. См пример:

#!/bin/bash

tkbash gui1 --theme clam --title "Привет Лор" --icon "tux.png" -w 550 -h 200 --drag 1

tkbash gui1 label  label1  -x 5   -y 5   -w 150 -h 30  --text "О Боже мой!"
tkbash gui1 label  label2  -x 5   -y 35  -w 150 -h 50  --text "Баш может в Гуй!"
tkbash gui1 select select1 -x 5   -y 66  -w 150 -h 30  --text "Кошмар|Ужас||Замечательно|???"

tkbash gui1 button button1 -x 155 -y 5   -w 250 -h 30  --text "Отправить глупость на ЛОР" --command "notify-send it"
tkbash gui1 edit   edit1   -x 155 -y 45  -w 250 -h 94  --text "Yorem Lipsum yolo git amet" --scrollbar 1 --background "grey" --foreground "yellow" --style "font:verdana 12"

tkbash gui1 image  image1  -x 425 -y 5   -w 125 -h 127 --image "tux0.png"

tkbash gui1 label  label4  -x 5   -y 120 -w 150 -h 30  --text "Лучший редактор?"
tkbash gui1 radio  radio1  -x 5   -y 140 -w 150 -h 30  --text "emacs" --group group1 --command 'tkbash gui1 label3 --text "Лучший текстовый редактор это $(tkbash gui1 get radio2)."'
tkbash gui1 radio  radio2  -x 5   -y 160 -w 150 -h 30  --text "emacs-nox" --group group1 --selected


tkbash gui1 label  label3  -x 155 -y 140 -w 395 -h 30 --text "?" --fg '#ff5555'

tkbash gui1 --hotkey Escape --command 'tkbash gui1 --close'

Результат

ugoday ★★★★★
()
Ответ на: комментарий от rtxtxtrx

я прошу прощения, но у меня все «тайминговые» лимиты на эту клоунаду исчерпаны, поэтому с вашего позволения я сольюсь

gagarin0
()
Ответ на: комментарий от gagarin0

Нет, конечно.

Если аргументом является то, что shmenu является TUI, то C и C++ тоже не являются TUI, хотя на них написано много программ, являющихся TUI.

monk ★★★★★
()
Ответ на: комментарий от FishHook

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

То есть, понятно, что sh и ed = CLI, vi = TUI, VSCode = GUI.

Куда отнести gvim и emacs/X? Это уже GUI или ещё TUI?

Куда отнести CLI, который может выводить объекты, по которым можно щёлкнуть мышью? Это уже TUI или GUI?

monk ★★★★★
()
Ответ на: комментарий от monk

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

rtxtxtrx ★★★
() автор топика
Ответ на: комментарий от monk

я всё ещё считаю, своё определение подходящим.

ИМХО, ключевая особенность что TUI, что GUI - это WYSIWYG. Поясню. Программа должна обеспечивать пользовательский ввод через графические виджеты - кнопки, списки, чекбоксы и так далее. Опционально там может быть накручено какое угодно количество альтернативных способов ввода, хоть по движению глаз, но графический способ зваимодействия в приложением быть обязан. Разница между TUI и GUI только в способе отрисовки виджетов. В этом плане vi я не считаю TUI программой, а например mc считаю.

FishHook
()
Ответ на: комментарий от gagarin0

@gagarin0 ты же уже самослился и сдристнул, разве нет? Как крыса втихую минусишь посты не обращая внимания на большие буквы ИМХО.

FishHook
()
Ответ на: комментарий от FishHook

WYSIWIG совсем не про TUI.

В этом плане vi я не считаю TUI программой

Куда отнести Emacs? Вроде нет классических виджетов, но «графический» выбор элементов есть.

Например, так: https://avatars.mds.yandex.net/i?id=d583cc9e08884b2000da7ea58533238f9c5b9890-4987522-images-thumbs&n=13

monk ★★★★★
()
Ответ на: комментарий от rtxtxtrx

ну с туями все просто: они в терминале работают и через псевдографику все выводят.

А если не через псевдографику? Вот это уже гуи?

https://habrastorage.org/r/w1560/getpro/habr/upload_files/4bc/9b7/c7c/4bc9b7c7cb9a6e24573b2a17be4a97b0.png

Или если в gnome-terminal?

monk ★★★★★
()
Ответ на: комментарий от monk

Куда отнести Emacs? Вроде нет классических виджетов, но «графический» выбор элементов есть.

а точно надо куда-то относить? Без этого жизнь поломается?

FishHook
()
Ответ на: комментарий от monk

а вывод картинок - это фича эмуляторов терминала. это не гуи. гагарин вообще другую ересь нес: что shell - это tui…

а шелл ничего не рисует, он лишь обрабатывает нажатие кнопок и «выводит» текст…

https://dev.to/tbhaxor/playing-with-ncurses-cursor-part-2-1gil

rtxtxtrx ★★★
() автор топика
Последнее исправление: rtxtxtrx (всего исправлений: 2)
Ответ на: комментарий от gagarin0

и что там не так?

Запоминай:

  • шелл - это интерпретатор команд и интерфейс (который != графический интерфейс) командной строки
  • терминал - это то место куда можно попасть, нажав на ctrl-alt-f3, графическая сессия тоже на одном из терминалов висит
  • эмулятор терминала - графическая программа, эумулирующая работу с настоящим терминалом
  • TUI - тупо приложение для терминала, где элементы интерфейса выполнены в виде псевдографики (символов юникода или набора из ascii, патченных шрифтов и тп)
rtxtxtrx ★★★
() автор топика
Последнее исправление: rtxtxtrx (всего исправлений: 1)
Ответ на: комментарий от gagarin0

Это shell. Что он табличками что-то выводит ничего не значит. Таблички это не графический и не текстовый интерфейс. Графический интерфейс - это окошечки, кнопочки, табы… TUI все это дело отображает с помощью псевдографики

rtxtxtrx ★★★
() автор топика
Для того чтобы оставить комментарий войдите или зарегистрируйтесь.