Рыба для пользователей bash
Это краткое руководство для тех, кто переходит с bash (или, в меньшей степени, других оболочек, таких как zsh или ksh) и хочет узнать, чем отличается fish. Fish намеренно не совместим с POSIX, и поэтому некоторые привычные вещи работают иначе.
Многие вещи похожи — обе оболочки в основном расширяют командную строку для выполнения команд, имеют конвейеры, перенаправления, переменные, шаблоны, используют вывод команд различными способами. Этот документ призван быстро показать различия.
Замены команд
Fish использует замены команд в виде (command) вместо $(command) (или `command`).
Кроме того, он разделяет их только по символам новой строки вместо $IFS. Если вам нужно разделить по чему-то другому, используйте string split, string split0 или string collect. Если эти команды используются в качестве последней в замене команды, созданные разделения сохраняются. Таким образом:
правильно обработает все возможные имена файлов.
Переменные
Fish устанавливает и удаляет переменные с помощью set вместо VAR=VAL и declare и unset и export. set принимает опции для определения области действия и экспортируемости переменной:
или для удаления переменных:
VAR=VAL операторы доступны как переопределения среды:
Fish не выполняет разделение слов. После того, как переменной присвоено значение, это значение остается неизменным, поэтому двойные кавычки при расширении переменных не так необходимы, как в bash. [1]
Например, вот bash
А вот fish:
Все переменные являются «массивами» (мы используем термин «списки»), а расширение переменной расширяется до всех её элементов, каждый элемент — как отдельный аргумент (как в bash's "${var[@]}") :
Конкретные элементы списка можно выбрать:
| [1] | zsh также по умолчанию не выполняет разделение слов (опция SH_WORD_SPLIT управляет этим) |
Шаблоны (глобы)
Fish поддерживает только * и ** шаблоны (и устаревший ? шаблон). Если шаблон не соответствует, команда завершается неудачно (как и в bash's failglob) , если команда не for, set или count, или если шаблон используется с переопределением среды (VAR=* command), в этом случае он расширяется до ничего (как в bash's nullglob опция).
Глоббинг не происходит на расширенных переменных, поэтому:
не будет соответствовать никаким файлам.
Нет никаких опций для управления глоббингом, поэтому он всегда ведет себя так.
Кавычки
Fish имеет два типа кавычек: "" и ''. В двойных кавычках расширяются переменные, в одинарных — нет.
Нет $'', вместо этого последовательности, которые должны были преобразовываться, преобразуются при отсутствии кавычек:
Обработка строк
Fish не имеет ${foo%bar}, ${foo#bar} и ${foo/bar/baz}. Вместо этого обработка строк выполняется встроенной командой string.
Специальные переменные
Некоторые переменные bash и их аналоги в fish:
-
$*,$@,$1и так далее:$argv -
$?:$status -
$$:$fish_pid -
$#: Нет переменной, используйте вместо этогоcount $argv -
$!:$last_pid -
$0:status filename -
$-: В основномstatus is-interactiveиstatus is-login
Замена процессов
Вместо <(command) fish использует (command | psub). Нет эквивалента >(command).
Обратите внимание, что оба эти элемента являются особенностями bash, и большинство вещей можно легко выразить без них. Например, вместо:
просто используйте:
так как source fish может считывать данные со стандартного ввода.
Heredocs
Fish не имеет <<EOF "heredocs". Вместо:
используйте:
или:
Кавычки следуют через символы новой строки.
Test (test, [, [[)
Fish имеет совместимую с POSIX test или [ встроенную команду. Нет [[, а test не принимает == как синоним =. Однако она может сравнивать числа с плавающей точкой.
set -q можно использовать для определения существования переменной или наличия определенного количества элементов (set -q foo[2]).
Арифметическое расширение
Fish не имеет $((i+1)) арифметического расширения, вычисления обрабатываются командой math:
Она может обрабатывать числа с плавающей точкой:
Провайдеры
Fish не использует переменные $PS1, $PS2 и так далее. Вместо этого провайдер — это результат функции fish_prompt, плюс функция fish_mode_prompt, если включен режим vi, и функция fish_right_prompt для правого провайдера.
Например, вот относительно простой провайдер bash:
и грубый эквивалент в fish:
Это демонстрирует некоторые различия:
- Fish предоставляет set_color для форматирования текста. Она может использовать 16 именованных цветов и также RGB последовательности (также можно использовать
set_color 5555FF) - Вместо введения особых экранирований, таких как
\hдля имени хоста, провайдер просто является функцией, поэтому вы можете использовать переменные, такие как$hostname. - Fish предлагает вспомогательные функции для добавления вещей в провайдер, например fish_vcs_prompt для отображения информации о системах контроля версий (git, mercurial, svn) и prompt_pwd для отображения укороченного $PWD (домашний каталог пользователя становится
~и любой компонент пути укорачивается).
По умолчанию провайдер достаточно функционален, и его код можно прочитать с помощью type fish_prompt.
Fish не имеет $PS2 для продолжения строк, а вместо этого строки отступают, чтобы показать, что командная строка еще не завершена.
Блоки и циклы
Конструкции блокирования в fish выглядят немного иначе. Они все начинаются со слова, заканчиваются end и не имеют второго стартового слова:
Fish не имеет until. Используйте while not или while !.
Встроенные команды и другие команды
Сейчас очевидно, что fish уделяет гораздо больше внимания своим встроенным командам и внешним командам, а не своей синтаксике. Вот некоторые полезные встроенные команды и их приблизительные аналоги в bash:
- string — заменяет большинство преобразований строк (
${i%foo}и др.) и также может использоваться вместоgrepиsedи т. д. - math — заменяет
$((i + 1))арифметику и также может выполнять действия с плавающей точкой и некоторые простые функции (синус и др.) - argparse — может обрабатывать разбор опций скрипта, для чего bash, вероятно, использует
getopt(zsh предоставляетzparseopts) - count может подсчитывать вещи и, следовательно, заменяет
$#и может использоваться вместоwc - status предоставляет информацию о состоянии оболочки, например, интерактивная ли она или каков текущий номер строки. Это заменяет
$-и$BASH_LINENOи другие переменные. seq(1)может использоваться как замена{1..10}диапазонному расширению. Если ваша ОС не поставляетseq, fish включает функцию замены.
© 2020 fish-shell developers
Licensed under the GNU General Public License, version 2.
https://fishshell.com/docs/3.2/fish_for_bash_users.html