Spec-Zone.ru › Fish 3.2

Введение

Это документация для fish, fриендли iнтерактивной shелл.

Shell — это программа, которая помогает управлять компьютером, запуская другие программы. fish предлагает командную строку, ориентированную на удобство и интерактивное использование.

В отличие от других оболочек, fish не следует стандарту POSIX, но всё же использует примерно ту же модель.

Некоторые из специальных функций fish:

  • Расширенный пользовательский интерфейс: подсветка синтаксиса, автодополнение, завершение по вводу и списки выбора, которые можно просматривать и фильтровать.
  • Не требуется настройка: fish разработан для немедленного использования без необходимости в обширной настройке.
  • Легкое программирование: Новые функции можно добавлять на ходу. Синтаксис легко изучить и использовать.

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

Если вы уже знакомы с другими оболочками, такими как bash, и хотите увидеть различия в программировании, см. Fish For Bash Users.

Установка и запуск

Этот раздел описывает, как установить, удалить, запустить и выйти из оболочки fish. Также объясняется, как сделать fish стандартной оболочкой.

Установка

Актуальные инструкции по установке последней версии fish находятся на домашней странице fish.

Чтобы установить версию fish для разработчиков, см. инструкции на странице проекта GitHub.

Запуск и выход

После установки fish откройте терминал. Если fish не является стандартной оболочкой:

  • Чтобы запустить оболочку fish, введите fish:

    > fish
    
  • Чтобы выйти из оболочки fish, введите exit:

    > exit
    

Выполнение Bash

Если fish является вашей стандартной оболочкой, и вы хотите скопировать команды из интернета, написанные на bash (стандартной оболочке большинства систем), вы можете поступить следующим образом:

  • Используйте команду bash с ключом -c для чтения из строки:

    > bash -c 'some bash command'
    
  • Используйте bash без ключа для открытия оболочки bash, которую вы можете использовать, а затем exit:

    > bash
    $ some bash command
    $ exit
    > _
    

Стандартная оболочка

Чтобы сделать fish стандартной оболочкой:

  • Добавьте строку /usr/local/bin/fish в /etc/shells.
  • Измените стандартную оболочку с помощью chsh -s /usr/local/bin/fish.

Подробные инструкции см. в Переключении на fish.

Удаление

Для удаления fish см. ЧАВО: Удаление fish.

Строка shebang

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

Скрипт, написанный на bash, должен иметь первую строку такого вида:

#!/bin/bash

Когда оболочка сообщает ядру о выполнении файла, она будет использовать интерпретатор /bin/bash.

Для скрипта, написанного на другом языке, просто замените /bin/bash интерпретатором для этого языка (например, /usr/bin/python для скрипта python или /usr/local/bin/fish для скрипта fish).

Эта строка необходима только при выполнении скриптов без указания интерпретатора. Для функций внутри fish или при выполнении скрипта с помощью fish /path/to/script, shebang не требуется (но не помешает!).

Обзор синтаксиса

Оболочки, такие как fish, используются путём ввода команд. Каждая команда fish следует одному основному синтаксису. Команда выполняется путём ввода имени команды, за которым следуют любые аргументы. Например:

echo hello world

Это вызывает команду echo. echo выводит свои аргументы на экран. В приведённом выше примере выходные данные составляют hello world. Всё в fish выполняется с помощью команд. Есть команды для повторения других команд, команды для присвоения переменных, команды для обработки группы команд как одной команды и т. д. Все эти команды следуют одному основному синтаксису.

Чтобы узнать больше о команде echo, прочитайте её страницу справки, набрав man echo. man — это команда для отображения страницы справки по заданной теме. Она принимает имя страницы справки для отображения в качестве аргумента. Есть страницы справки для почти каждой команды. Также существуют страницы справки для многих других вещей, таких как системные библиотеки и важные файлы.

Каждая программа на вашем компьютере может использоваться как команда в fish. Если файл программы находится в одном из каталогов PATH, вы можете просто ввести имя программы, чтобы использовать её. В противном случае необходимо указать полное имя файла, включая каталог (например, /home/me/code/checkers/checkers или ../checkers).

Вот список некоторых полезных команд:

  • cd: Изменить текущий каталог
  • ls: Список файлов и каталогов
  • man: Отображение страницы справки
  • mv: Переместить (переименовать) файлы
  • cp: Копировать файлы
  • open: Открытие файлов с помощью стандартного приложения, связанного с каждым типом файла
  • less: Отображение содержимого файлов

Команды и аргументы разделяются символом пробела ' '. Каждая команда завершается либо новой строкой (нажатием клавиши ввода), либо точкой с запятой ;. Несколько команд могут быть записаны в одной строке, разделяясь точками с запятой.

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

Ключи различаются для каждой команды и обычно документируются на странице справки команды. Однако некоторые ключи являются общими для большинства команд. Например, --help обычно отображает текст справки, --version обычно отображает версию команды, а -i часто включает интерактивное приглашение перед выполнением действия.

Терминология

Здесь мы определяем некоторые термины, используемые на этой странице и в других разделах документации fish:

  • Аргумент: Параметр, передаваемый команде.
  • Встроенная команда: Команда, реализованная оболочкой. Встроенные команды так тесно связаны с работой оболочки, что их невозможно реализовать как внешние команды.
  • Команда: Программа, которую может запустить оболочка, или, точнее, внешняя программа, которую оболочка запускает в другом процессе.
  • Функция: Блок команд, который можно вызвать как одну команду. С помощью функций можно объединить несколько простых команд в одну более сложную команду.
  • Задача: Запущенная цепочка команд или команда.
  • Цепочка команд: Набор команд, соединённых так, что выход одной команды является входом следующей команды.
  • Перенаправление: Операция, изменяющая один из входных или выходных потоков, связанных с задачей.
  • Ключ или Опция: Специальный тип аргумента, изменяющий поведение команды. Ключ почти всегда начинается с одного или двух дефисов.

Кавычки

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

Единственными значимыми последовательностями экранирования в одинарных кавычках являются \', экранирующее одинарную кавычку, и \\, экранирующее обратную косую черту. Единственными значимыми экранированиями в двойных кавычках являются \", экранирующее двойную кавычку, \$, экранирующее символ доллара, \ с последующей новой строкой, удаляющее обратную косую черту и новую строку, и \\, экранирующее обратную косую черту.

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

Пример:

rm "cumbersome filename.txt"

удаляет файл cumbersome filename.txt, а

rm cumbersome filename.txt

удаляет два файла, cumbersome и filename.txt.

Другой пример:

grep 'enabled)$' foo.txt

ищет строки, заканчивающиеся на enabled) в foo.txt ($ является специальным для grep: он соответствует концу строки).

Экранирование символов

Некоторые символы нельзя вводить непосредственно в командной строке. Для этих символов предоставлены так называемые последовательности экранирования. Это:

  • \a представляет символ тревоги.
  • \e представляет символ escape.
  • \f представляет символ перевода страницы.
  • \n представляет символ новой строки.
  • \r представляет символ возврата каретки.
  • \t представляет символ табуляции.
  • \v представляет символ вертикальной табуляции.
  • \xHH, где HH — шестнадцатеричное число, представляет символ ASCII с указанным значением. Например, \x9 — символ табуляции.
  • \XHH, где HH — шестнадцатеричное число, представляет байт данных с указанным значением. Если вы используете многобайтовую кодировку, это можно использовать для ввода неверных строк. Используйте это только в том случае, если вы знаете, что делаете.
  • \ooo, где ooo — восьмеричное число, представляет символ ASCII с указанным значением. Например, \011 — символ табуляции.
  • \uXXXX, где XXXX — шестнадцатеричное число, представляет 16-битный символ Unicode с указанным значением. Например, \u9 — символ табуляции.
  • \UXXXXXXXX, где XXXXXXXX — шестнадцатеричное число, представляет 32-битный символ Unicode с указанным значением. Например, \U9 — символ табуляции.
  • \cX, где X — буква алфавита, представляет управляющую последовательность, генерируемую нажатием клавиши управления и указанной буквы. Например, \ci — символ табуляции

Некоторые символы имеют специальное значение для оболочки. Например, апостроф ' отключает расширение (см. Кавычки). Чтобы оболочка обрабатывала эти символы буквально, экранируйте их обратной косой чертой. Например, команда:

echo \'hello world\'

выводит 'hello world' (включая апострофы), а команда:

echo 'hello world'

выводит hello world (без апострофов). В первом случае оболочка обрабатывает апострофы как буквальные ' символы, а во втором случае — как специальные модификаторы расширения.

Специальные символы и их последовательности экранирования:

  • \ (обратная косая черта пробел) экранирует пробел. Это предотвращает разделение аргументов оболочкой на пробелы.
  • \$ экранирует символ доллара.
  • \\ экранирует символ обратной косой черты.
  • \* экранирует символ звёздочки.
  • \? экранирует символ вопроса (это необязательно, если qmark-noglob флаг функции включён).
  • \~ экранирует символ тильды.
  • \# экранирует символ решётки.
  • \( экранирует символ левой круглой скобки.
  • \) экранирует символ правой круглой скобки.
  • \{ экранирует символ левой фигурной скобки.
  • \} экранирует символ правой фигурной скобки.
  • \[ экранирует символ левой квадратной скобки.
  • \] экранирует символ правой квадратной скобки.
  • \< экранирует символ меньше.
  • \> экранирует символ больше.
  • \^ экранирует символ циркумфлекса.
  • \& экранирует символ амперсанда.
  • \| экранирует символ вертикальной черты.
  • \; экранирует символ точки с запятой.
  • \" экранирует символ кавычки.
  • \' экранирует символ апострофа.

Перенаправление ввода/вывода

Большинство программ используют три потока ввода/вывода (I/O):

  • Стандартный ввод (stdin) для чтения. По умолчанию читает с клавиатуры.
  • Стандартный вывод (stdout) для записи вывода. По умолчанию записывает на экран.
  • Стандартная ошибка (stderr) для записи ошибок и предупреждений. По умолчанию записывает на экран.

Каждый поток имеет номер, называемый дескриптором файла (FD): 0 для stdin, 1 для stdout и 2 для stderr.

Назначение потока может быть изменено с помощью перенаправления. Например, echo hello > output.txt, перенаправляет стандартный вывод команды echo в текстовый файл.

  • Для чтения стандартного ввода из файла используйте <SOURCE_FILE.
  • Для записи стандартного вывода в файл используйте >DESTINATION.
  • Для записи стандартной ошибки в файл используйте 2>DESTINATION.[1]
  • Для добавления стандартного вывода в файл используйте >>DESTINATION_FILE.
  • Для добавления стандартной ошибки в файл используйте 2>>DESTINATION_FILE.
  • Чтобы не перезаписывать существующий файл, используйте >?DESTINATION или 2>?DESTINATION Это известно как перенаправление "noclobber".

DESTINATION может быть одним из следующих:

  • Имя файла. Вывод будет записан в указанный файл. Часто >/dev/null для подавления вывода, записывая его в специальный файл "поглотитель".
  • Амперсанд (&) за которым следует номер другого дескриптора файла, например &2 для стандартной ошибки. Вывод будет записан в указанный дескриптор.
  • Амперсанд, за которым следует знак минус (&-). Дескриптор файла будет закрыт.

Для удобства перенаправление &> может использоваться для перенаправления stdout и stderr в одно и то же место назначения. Например, echo hello &> all_output.txt перенаправляет stdout и stderr в файл all_output.txt. Это эквивалентно echo hello > all_output.txt 2>&1.

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

  • Для перенаправления ввода дескриптора N используйте N<DESTINATION.
  • Для перенаправления вывода дескриптора N используйте N>DESTINATION.
  • Для добавления вывода дескриптора N в файл используйте N>>DESTINATION_FILE.

Например, echo hello 2> output.stderr записывает стандартную ошибку (дескриптор файла 2) в output.stderr.

Перенаправление встроенной функции или блока в дескриптор файла выше 2 является ошибкой. Однако это поддерживается для внешних команд.

[1] Предыдущие версии fish также допускали указание этого как ^DESTINATION, но это делало другой символ специальным, поэтому это было устарело и будет удалено в будущем. Смотрите флаги функций.

Помещение

Другой способ перенаправить потоки — это помещение. Помещение соединяет потоки друг с другом. Обычно стандартный вывод одной команды подключается к стандартному вводу другой. Это делается путём разделения команд символом помещения |. Например:

cat foo.txt | head

Команда cat foo.txt отправляет содержимое foo.txt на stdout. Этот вывод поступает на вход программе head, которая выводит первые 10 строк своего ввода.

Возможна передача другого дескриптора вывода путем добавления его номера FD и символа перенаправления вывода перед помещением. Например:

make fish 2>| less

попытается создать fish, и любые ошибки будут отображены с помощью пагинатора less [2]

Для удобства размещение &| перенаправляет stdout и stderr в один и тот же процесс. Обратите внимание, что это отличается от bash, который использует |&.

[2] "Пагинатор" здесь — это программа, которая принимает вывод и "разбивает" его на страницы. less не просто страницы, оно позволяет произвольное прокручивание (даже назад!).

Управление задачами

Когда вы запускаете задачу в fish, сам fish приостанавливает работу и передает управление терминалом запущенной программе. Иногда вам нужно продолжить работу с командной строкой и запустить задачу в фоновом режиме. Для создания фоновой задачи добавьте & (амперсанд) к вашей команде. Это сообщит fish о запуске задачи в фоновом режиме. Фоновые задачи очень полезны при запуске программ с графическим интерфейсом пользователя.

Пример:

emacs &

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

Большинство программ позволяют приостановить выполнение программы и вернуть управление fish нажатием Control+Z (также называемый ^Z). После возврата в командную строку fish вы можете запустить другие программы и делать всё, что захотите. Если затем вы захотите вернуться к приостановленной команде, используйте команду fg (фоновый режим).

Если вы хотите поместить приостановленную задачу в фоновый режим, используйте команду bg.

Чтобы получить список всех запущенных задач, используйте команду jobs. Эти задачи можно удалить с помощью команды disown.

Обратите внимание, что функции не могут быть запущены в фоновом режиме. Функции, которые приостановлены и затем перезапущены в фоновом режиме с помощью команды bg, не будут выполняться правильно.

Функции

Функции — это программы, написанные на синтаксисе fish. Они группируют различные команды и их аргументы под одним именем.

Например, вот простая функция для вывода каталогов:

function ll
    ls -l $argv
end

Первая строка говорит Fish о необходимости определить функцию с именем ll, чтобы её можно было использовать, просто написав ll в командной строке. Вторая строка указывает Fish, что команду ls -l $argv нужно вызвать, когда вызывается ll. $argv — это переменная-список, которая всегда содержит все аргументы, переданные функции. В приведённом примере эти аргументы просто передаются команде ls. end в третьей строке завершает определение.

Вызов этого как ll /tmp/ приведет к запуску ls -l /tmp/, которая выведет содержимое /tmp.

Это своего рода функция, известная как обёртка или «псевдоним».

Промпт Fish также определён в функции с именем fish_prompt. Она выполняется при отображении промпта, и её вывод формирует сам промпт:

function fish_prompt
    # A simple prompt. Displays the current directory
    # (which fish stores in the $PWD variable)
    # and then a user symbol - a '►' for a normal user and a '#' for root.
    set -l user_char '►'
    if fish_is_root_user
        set user_char '#'
    end

    echo (set_color yellow)$PWD (set_color purple)$user_char
end

Для редактирования функции можно использовать funced, а для сохранения функции — funcsave. Это сохранит её в файле функции, который Fish будет автоматически загружать при необходимости.

Встроенная команда functions может показать текущее определение функции (и type сделает то же самое, если ей передать имя функции).

Дополнительную информацию о функциях можно найти в документации по встроенной команде function.

Определение псевдонимов

Одно из наиболее распространённых применений функций — небольшое изменение поведения уже существующей команды. Например, можно переопределить команду ls для отображения цвета. Переключатель для включения цвета в системах GNU — --color=auto. Псевдоним или обёртка вокруг ls может выглядеть следующим образом:

function ls
    command ls --color=auto $argv
end

Следует обратить внимание на несколько важных моментов, касающихся псевдонимов:

  • Всегда добавляйте переменную $argv в список параметров оборачиваемой команды. Это гарантирует, что если пользователь укажет дополнительные параметры функции, они будут переданы основной команде.
  • Если псевдоним имеет то же имя, что и оборачиваемая команда, необходимо префикс command при вызове программы, чтобы указать Fish, что функция не должна вызывать себя, а должна вызвать команду с тем же именем. Если вы забудете это сделать, функция будет вызывать себя до бесконечности. Обычно Fish достаточно умён, чтобы это понять и воздерживаться от этого (надеюсь, это в ваших интересах).
  • Автоматическая загрузка не применима к псевдонимам. По определению, функция создается в момент выполнения команды псевдонима. Загружать псевдонимы автоматически нельзя.

Для лёгкого создания функции такого типа можно использовать команду alias. В отличие от других оболочек, она просто создаёт функции — Fish не имеет отдельной концепции «псевдонима», мы просто используем это слово для описания функции-обёртки.

В качестве альтернативы можно попробовать сокращения. Это слова, которые расширяются во время ввода, а не являются фактическими функциями внутри оболочки.

Автоматическая загрузка функций

Функции могут быть определены в командной строке или в файле конфигурации, но их также можно загружать автоматически. Это имеет некоторые преимущества:

  • Автоматически загружаемая функция становится доступной для всех работающих оболочек.
  • Если определение функции изменено, все работающие оболочки автоматически перезагрузят изменённую версию через некоторое время.
  • Улучшается время запуска и использование памяти и т. д.

Когда Fish нужно загрузить функцию, он ищет в каталогах из переменной-списка $fish_function_path файл с именем, состоящим из имени функции и суффикса .fish, и загружает первый найденный файл.

По умолчанию $fish_function_path содержит следующее:

  • Директория для конечных пользователей, чтобы хранить свои собственные функции, обычно ~/.config/fish/functions (управляется переменной среды XDG_CONFIG_HOME).
  • Директория для системных администраторов, чтобы устанавливать функции для всех пользователей в системе, обычно /etc/fish/functions (на самом деле $__fish_sysconfdir/functions).
  • Директории для другого программного обеспечения, чтобы размещать свои собственные функции. Они находятся в каталогах в переменной среды XDG_DATA_DIRS, в подкаталоге fish/vendor_functions.d. По умолчанию это обычно /usr/share/fish/vendor_functions.d и /usr/local/share/fish/vendor_functions.d.
  • Функции, поставляемые с Fish, обычно установленные в /usr/share/fish/functions (на самом деле $__fish_data_dir/functions).

Если вы не уверены, ваши функции, вероятно, должны находиться в ~/.config/fish/functions.

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

Если вы разрабатываете другую программу и хотите установить функции Fish для неё, установите их в директорию функций «vendor». Поскольку этот путь различается в разных системах, вы можете использовать pkgconfig для его обнаружения с помощью вывода pkg-config --variable functionsdir fish. Ваша система установки должна поддерживать пользовательский путь для переопределения пути pkgconfig, поскольку другим дистрибутивам может потребоваться легко его изменить.

Комментарии

Всё, что следует за # до конца строки, является комментарием. Это означает, что он предназначен только для читателя; Fish его игнорирует.

Это полезно для объяснения того, что и почему вы делаете:

function ls
    # The function is called ls,
    # so we have to explicitly call `command ls` to avoid calling ourselves.
    command ls --color=auto $argv
end

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

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

set -gx EDITOR emacs # I don't like vim.

Условные операторы

Fish имеет некоторые встроенные команды, позволяющие выполнять команды только в том случае, если выполняется определённое условие: if, switch, and и or, а также знакомый синтаксис &&/||.

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

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

В отличие от языков программирования, которые вам могут быть известны, if не принимает условие, а принимает команду. Если эта команда вернула успешный код возврата (то есть 0), выбирается ветвь if, в противном случае — ветвь else.

Примеры:

# Just see if the file contains the string "fish" anywhere.
# This executes the `grep` command, which searches for a string,
# and if it finds it returns a status of 0.
# The `-q` switch stops it from printing any matches.
if grep -q fish myanimals
    echo "You have fish!"
else
    echo "You don't have fish!"
end

# $XDG_CONFIG_HOME is a standard place to store configuration.
# If it's not set applications should use ~/.config.
set -q XDG_CONFIG_HOME; and set -l configdir $XDG_CONFIG_HOME
or set -l configdir ~/.config

Дополнительную информацию см. в документации по встроенным командам или в разделе Условные операторы руководства.

Циклы и блоки

Как и большинство языков программирования, Fish также имеет знакомые циклы while и for.

while работает как повторяющийся if:

while true
    echo Still running
    sleep 1
end

будет выводить "Still running" каждую секунду. Вы можете прервать его, нажав Ctrl+C.

Циклы for работают так же, как и в других оболочках, что больше похоже на циклы for в Python, чем, например, в C:

for file in *
    echo file: $file
end

будет выводить каждый файл в текущей директории. Часть после in — это просто список аргументов, поэтому вы можете использовать любые расширения:

set moreanimals bird fox
for animal in {cat,}fish dog $moreanimals
   echo I like the $animal
end

Если вам нужен список чисел, вы можете использовать команду seq для его создания:

for i in (seq 1 5)
    echo $i
end

break доступна для выхода из цикла, а continue — для перехода к следующей итерации.

Перенаправление ввода и вывода (включая каналы) также могут применяться к циклам:

while read -l line
    echo line: $line
end < file

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

begin
   set -l foo bar # this variable will only be available in this block!
end

Расширение параметров

Когда Fish получает командную строку, он расширяет параметры перед передачей их команде. Существует несколько различных типов расширений:

  • Подстановки шаблонов, для создания имён файлов из шаблонов
  • Подстановка переменных, для использования значения переменной
  • Подстановка команд, для использования вывода другой команды
  • Подстановка фигурных скобок, для краткого записи списков с общими префиксами или суффиксами
  • Подстановка тильды, для преобразования ~ в начале путей к пути домашнего каталога

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

Подстановки шаблонов ("Глоббинг")

Когда параметр содержит необрамлённую * звезду (или "звёздочку") или ? знак вопроса, fish использует их как подстановки шаблонов для сопоставления файлов.

  • * соответствует любому количеству символов (включая ноль) в имени файла, не включая /.
  • ** соответствует любому количеству символов (включая ноль), а также спускается в подкаталоги. Если ** является отдельным сегментом, этот сегмент может соответствовать нулю раз для совместимости с другими оболочками.
  • ? может соответствовать любому одиночному символу, кроме /. Это устаревший параметр и может быть отключён через qmark-noglob флаг функции, поэтому ? будет просто обычным символом.

Другие оболочки, такие как zsh, имеют более богатый синтаксис подстановок шаблонов, например **(.) для сопоставления только обычных файлов. Fish этого не делает. Вместо того, чтобы изобретать велосипед, используйте программы, такие как find для поиска файлов. Например:

function ff --description 'Like ** but only returns plain files.'
    # This also ignores .git directories.
    find . \( -name .git -type d -prune \) -o -type f | \
        sed -n -e '/^\.\/\.git$/n' -e 's/^\.\///p'
end

Затем вы можете использовать его вместо ** следующим образом, my_prog (ff), чтобы передать только обычные файлы в или ниже $PWD в my_prog. [3]

Сопоставления с подстановками шаблонов сортируются без учёта регистра. При сортировке сопоставлений, содержащих числа, они сортируются в естественном порядке, так что строки '1', '5' и '12' будут отсортированы как 1, 5, 12.

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

Примеры:

  • a* соответствует любым файлам, начинающимся с 'a' в текущем каталоге.
  • ??? соответствует любому файлу в текущем каталоге, имя которого состоит ровно из трёх символов.
  • ** соответствует любым файлам и каталогам в текущем каталоге и всех его подкаталогах.
  • ~/.* соответствует всем скрытым файлам (также известным как "dotfiles") и каталогам в вашем домашнем каталоге.

Для большинства команд, если ни одна подстановка шаблонов не расширится, команда не выполняется, $status устанавливается в ненулевое значение, и выводится предупреждение. Это поведение аналогично тому, что делает bash с shopt -s failglob. Существует ровно 4 исключения, а именно set, переопределение переменных в переопределениях, count и for. Их подстановки шаблонов вместо этого расширятся до нуля аргументов (так что команда их вообще не увидит), как с shopt -s nullglob в bash.

Примеры:

# List the .foo files, or warns if there aren't any.
ls *.foo

# List the .foo files, if any.
set foos *.foo
if count $foos >/dev/null
    ls $foos
end
[3] Технически, unix разрешает имена файлов с символами новой строки, и это разбивает find вывод на новые строки. Если вы хотите этого избежать, используйте опцию -print0 find и string split0.

Подстановка переменных

Одной из важнейших подстановок в fish является "подстановка переменных". Это замена знака доллара ($) за которым следует имя переменной на _значение_ этой переменной. Подробнее о переменных оболочки см. раздел Переменные оболочки.

В простейшем случае это выглядит примерно так:

echo $HOME

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

Иногда переменная не имеет значения, потому что она не определена или пуста, и она расширяется до ничего:

echo $nonexistentvariable
# Prints no output.

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

echo The plural of $WORD is "$WORD"s
# Prints "The plural of cat is cats" when $WORD is set to cat.
echo The plural of $WORD is {$WORD}s
# ditto

Обратите внимание, что без кавычек или фигурных скобок fish попытается расширить переменную, которая называется $WORDs, которая может не существовать.

Последний синтаксис {$WORD} является частным случаем подстановки фигурных скобок.

Если $WORD здесь не определена или пустой список, "s" не будет выведено. Однако, он будет выведен, если $WORD - пустая строка (например, после set WORD "").

В отличие от всех других подстановок, подстановка переменных также происходит в двойных кавычках. В двойных кавычках ("these") переменные всегда будут расширяться ровно до одного аргумента. Если они пустые или не определены, результат - пустая строка. Если у них один элемент, то будет расширено до этого элемента. Если у них более одного элемента, элементы будут объединены пробелами, если переменная не является переменной пути — в этом случае она будет использовать двоеточие (:) вместо [4].

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

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

Символ $ также может использоваться несколько раз как оператор "ссылка" (аналог * в C или C++), как в следующем коде:

set foo a b c
set a 10; set b 20; set c 30
for i in (seq (count $$foo))
    echo $$foo[$i]
end

# Output is:
# 10
# 20
# 30

$$foo[$i] — это "значение переменной, имя которой $foo[$i].

При использовании этой функции вместе с квадратными скобками, скобки будут использоваться изнутри наружу. $$foo[5] будет использовать пятый элемент $foo в качестве имени переменной, а не пятый элемент всех переменных, к которым относится $foo. Это вместо этого выражается как $$foo[1][5] (взять первый элемент $foo, использовать его как имя переменной, а затем дать пятый элемент этого).

[4] В отличие от bash или zsh, которые объединяют с первым символом $IFS (который обычно является пробелом).

Подстановка команд

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

Когда вы пишете команду в скобках, например outercommand (innercommand), то innercommand выполняется в первую очередь. Её вывод будет взят, и каждая строка будет передана в качестве отдельного аргумента команде outercommand, которая затем будет выполнена. [5]

Если вывод перенаправляется в string split или string split0 как последняя операция, эти разделения используются как есть, вместо разделения строк.

Код возврата последней выполненной подстановки команды доступен в переменной status, если подстановка происходит в контексте команды set (так что if set -l (something) проверяет, вернул ли something значение true).

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

Fish имеет стандартное ограничение на данные, которые он будет считывать в подстановке команды, равное 100 МБ. Если это ограничение достигнуто, команда (вся, а не только подстановка команды - внешняя команда вообще не будет выполнена) завершается неудачей, и $status устанавливается в 122. Это делается для того, чтобы подстановки команд не приводили к исчерпанию памяти системы, так как обычно в вашей операционной системе есть гораздо более низкое ограничение, поэтому чтение большего количества данных было бы бесполезным и вредным. Это ограничение можно настроить с помощью переменной fish_read_limit (0 означает отсутствие ограничения). Это ограничение также влияет на команду read.

Примеры:

# Outputs 'image.png'.
echo (basename image.jpg .jpg).png

# Convert all JPEG files in the current directory to the
# PNG format using the 'convert' program.
for i in *.jpg; convert $i (basename $i .jpg).png; end

# Set the ``data`` variable to the contents of 'data.txt'
# without splitting it into a list.
begin; set -l IFS; set data (cat data.txt); end

# Set ``$data`` to the contents of data, splitting on NUL-bytes.
set data (cat data | string split0)

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

grep fish myanimallist1 | wc -l

но если вам нужны несколько файлов или команда не читает со стандартного ввода, «замена процесса» полезна. Другие оболочки [6] позволяют это через foo <(bar) <(baz), и fish использует команду psub:

# Compare just the lines containing "fish" in two files:
diff -u (grep fish myanimallist1 | psub) (grep fish myanimallist2 | psub)

Это создаёт временный файл, сохраняет вывод команды в этом файле и выводит имя файла, чтобы он передавался внешней команде.

[5] Установление $IFS в пустое значение отключит разделение строк. Это устаревший способ, используйте разделение строк вместо него.
[6] По крайней мере, Bash и Zsh, хотя это расширение POSIX

Расширение фигурных скобок

Фигурные скобки могут использоваться для записи списков, разделённых запятыми. Они будут расширены, и каждый элемент станет новым параметром с прикреплённой к нему окружающей строкой. Это полезно для экономии набора текста и для разделения имени переменной от окружающего текста.

Примеры:

> echo input.{c,h,txt}
input.c input.h input.txt

# Move all files with the suffix '.c' or '.h' to the subdirectory src.
> mv *.{c,h} src/

# Make a copy of `file` at `file.bak`.
> cp file{,.bak}

> set -l dogs hot cool cute "good "
> echo {$dogs}dog
hotdog cooldog cutedog good dog

Если между фигурными скобками нет запятой или расширения переменной, они не будут расширены:

# This {} isn't special
> echo foo-{}
foo-{}
# This passes "HEAD@{2}" to git
> git reset --hard HEAD@{2}
> echo {{a,b}}
{a} {b} # because the inner brace pair is expanded, but the outer isn't.

Если после расширения между фигурными скобками ничего не остаётся, аргумент будет удалён (см. раздел декартова произведения):

> echo foo-{$undefinedvar}
# Output is an empty line, just like a bare `echo`.

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

> echo {,,/usr}/bin
/bin /bin /usr/bin

Чтобы использовать запятую как элемент, обратите или экранируйте её.

Объединение списков (Декартово произведение)

Когда списки расширяются с прикреплёнными к ним другими частями, они расширяются с этими частями, которые по-прежнему прикреплены. Даже если два списка прикреплены друг к другу, они расширяются во всех комбинациях. Это называется cartesian product (как в математике) и работает в основном как расширение фигурных скобок.

Примеры:

# Brace expansion is the most familiar:
# All elements in the brace combine with the parts outside of the braces
>_ echo {good,bad}" apples"
good apples bad apples

# The same thing happens with variable expansion.
>_ set -l a x y z
>_ set -l b 1 2 3

# $a is {x,y,z}, $b is {1,2,3},
# so this is `echo {x,y,z}{1,2,3}`
>_ echo $a$b
x1 y1 z1 x2 y2 z2 x3 y3 z3

# Same thing if something is between the lists
>_ echo $a"-"$b
x-1 y-1 z-1 x-2 y-2 z-2 x-3 y-3 z-3

# Or a brace expansion and a variable
>_ echo {x,y,z}$b
x1 y1 z1 x2 y2 z2 x3 y3 z3

# A combined brace-variable expansion
>_ echo {$b}word
1word 2word 3word

# Special case: If $c has no elements, this expands to nothing
>_ echo {$c}word
# Output is an empty line

Иногда это может быть нежелательно, особенно, что токены могут исчезнуть после расширения. В этих случаях вы должны заключить переменные в двойные кавычки - echo "$c"word.

Это также происходит после подстановки команд. Чтобы избежать исчезновения токенов, заставьте внутреннюю команду возвращать заключительную новую строку или сохраните вывод в переменную и заключите её в двойные кавычки.

Например,

>_ set b 1 2 3
>_ echo (echo x)$b
x1 x2 x3
>_ echo (printf '%s' '')banana
# the printf prints nothing, so this is nothing times "banana",
# which is nothing.
>_ echo (printf '%s\n' '')banana
# the printf prints a newline,
# so the command substitution expands to an empty string,
# so this is `''banana`
banana

Это может быть очень полезно. Например, если вы хотите пройтись по всем файлам во всех директориях в $PATH, используйте:

for file in $PATH/*

Поскольку $PATH — это список, это расширяется до всех файлов во всех директориях в нём. А если в $PATH нет директорий, правильный ответ здесь — расширение до отсутствия файлов.

Расширение диапазона индексов

Иногда необходимо получить доступ только к некоторым элементам списка или некоторым строкам вывода подстановки команд. В обоих случаях в fish это возможно, записав набор индексов в квадратных скобках, например:

$var[2]
# or
$var[1..3]

В квадратных скобках индексов fish понимает диапазоны, записанные как a..b («a» и «b» — индексы). Они расширяются в последовательность индексов от a до b (так a a+1 a+2 ... b), увеличиваясь, если b больше, и уменьшаясь, если a больше. Также можно использовать отрицательные индексы — они берутся с конца списка, так что -1 — это последний элемент, а -2 — тот, что перед ним. Если индекс не существует, диапазон ограничивается ближайшим возможным индексом.

Если список имеет 5 элементов, индексы идут от 1 до 5, поэтому диапазон 2..16 будет охватывать только элементы с 2 по 5.

Если конец отрицательный, диапазон всегда увеличивается, поэтому 2..-2 будет идти от элемента 2 до 4, а 2..-16 не пойдёт никуда, потому что нет способа перейти от второго элемента к несуществующему, увеличиваясь. Если начало отрицательное, диапазон всегда уменьшается, поэтому -2..1 будет идти от элемента 4 до 1, а -16..2 не пойдёт никуда, потому что нет способа перейти от второго элемента к несуществующему, уменьшаясь.

Пропущенный начальный индекс в диапазоне по умолчанию равен 1. Это разрешено, если диапазон является первым выражением индекса в последовательности. Аналогично, пропущенный конечный индекс, по умолчанию равный -1, разрешён для последнего диапазона индекса в последовательности.

Также возможны несколько диапазонов, разделённых пробелом.

Некоторые примеры:

echo (seq 10)[1 2 3]
# Prints: 1 2 3

# Limit the command substitution output
echo (seq 10)[2..5]
# Uses elements from 2 to 5
# Output is: 2 3 4 5

echo (seq 10)[7..]
# Prints: 7 8 9 10

# Use overlapping ranges:
echo (seq 10)[2..5 1..3]
# Takes elements from 2 to 5 and then elements from 1 to 3
# Output is: 2 3 4 5 1 2 3

# Reverse output
echo (seq 10)[-1..1]
# Uses elements from the last output line to
# the first one in reverse direction
# Output is: 10 9 8 7 6 5 4 3 2 1

# The command substitution has only one line,
# so these will result in empty output:
echo (echo one)[2..-1]
echo (echo one)[-3..1]

То же самое работает при установке или расширении переменных:

# Reverse path variable
set PATH $PATH[-1..1]
# or
set PATH[-1..1] $PATH

# Use only n last items of the PATH
set n -3
echo $PATH[$n..-1]

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

set index 2
set letters a b c d
echo $letters[$index] # returns 'b'

Однако использование переменных в качестве индексов для подстановки команд в настоящее время не поддерживается, поэтому:

echo (seq 5)[$index] # This won't work

set sequence (seq 5) # It needs to be written on two lines like this.
echo $sequence[$index] # returns '2'

При использовании косвенного расширения переменных с несколькими $ ($$name), вы должны указать все индексы до переменной, которую вы хотите нарезать:

> set -l list 1 2 3 4 5
> set -l name list
> echo $$name[1]
1 2 3 4 5
> echo $$name[1..-1][1..3] # or $$name[1][1..3], since $name only has one element.
1 2 3

Расширение домашней директории

Символ ~ (тильда) в начале параметра, за которым следует имя пользователя, расширяется до домашней директории указанного пользователя. Одиночная ~, или ~, за которой следует слэш, расширяется до домашней директории владельца процесса:

ls ~/Music # lists my music directory

echo ~root # prints root's home directory, probably "/root"

Объединение различных расширений

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

При объединении нескольких расширений параметров расширения выполняются в следующем порядке:

  • Подстановки команд
  • Расширения переменных
  • Расширение в квадратных скобках
  • Расширение по маске

Расширения выполняются справа налево, вложенные расширения в квадратных скобках выполняются изнутри наружу.

Пример:

Если в текущей директории содержатся файлы 'foo' и 'bar', команда echo a(ls){1,2,3} выведет abar1 abar2 abar3 afoo1 afoo2 afoo3.

Переменные оболочки

Переменные — это способ сохранения данных и передачи их. Они могут использоваться только оболочкой или могут быть "экспортированы", чтобы копия переменной была доступна любой внешней команде, которую запускает оболочка. Экспортированная переменная называется "переменной среды".

Для установки значения переменной используйте команду set. Имя переменной не может быть пустым и может содержать только буквы, цифры и символы нижнего подчёркивания. Оно может начинаться и заканчиваться любым из этих символов.

Пример:

Для установки переменной smurf_color со значением blue используйте команду set smurf_color blue.

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

Пример:

set smurf_color blue
echo Smurfs are usually $smurf_color
set pants_color red
echo Papa smurf, who is $smurf_color, wears $pants_color pants

Таким образом, вы устанавливаете переменную с set, и используете её с $ и именем.

Область действия переменных

В fish существуют три вида переменных: универсальные, глобальные и локальные.

  • Универсальные переменные разделяются между всеми сессиями fish, которые пользователь запускает на одном компьютере.
  • Глобальные переменные относятся к текущей сессии fish и никогда не будут удалены, если явно не запросить их удаление, используя set -e.
  • Локальные переменные относятся к текущей сессии fish и связаны с определённым блоком команд, и автоматически удаляются, когда блок выходит из области видимости. Блок команд — это последовательность команд, которая начинается с одной из команд for, while, if, function, begin или switch, и заканчивается командой end.

Переменные могут быть явно установлены как универсальные с флагом -U или --universal, глобальные с флагом -g или --global, или локальные с флагом -l или --local. Правила области действия при создании или обновлении переменной таковы:

  • Если явно указана область действия, она будет использоваться. Если переменная с тем же именем существует в другой области действия, эта переменная не будет изменена.
  • Если область действия не указана, но переменная с таким именем существует, будет изменена переменная с наименьшей областью действия. Область действия не изменится.
  • В качестве специального случая, если область действия не указана и переменная не определена, переменная будет принадлежать области действия выполняемой в данный момент _функции_. Обратите внимание, что это отличается от флага --local, который сделал бы переменную локальной для текущего _блока_.

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

Пример:

Существует несколько возможных применений для разных областей действия.

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

function something
    set -l file /path/to/my/file
    if not test -e "$file"
        set file /path/to/my/otherfile
    end
end

Если вы хотите установить что-то в config.fish или установить что-то в функции и сделать его доступным для остальной части сессии, глобальная область действия — хороший выбор:

# Don't shorten the working directory in the prompt
set -g fish_prompt_pwd_dir_length 0

# Set my preferred cursor style:
function setcursors
   set -g fish_cursor_default block
   set -g fish_cursor_insert line
   set -g fish_cursor_visual underscore
end

# Set my language (also :ref:`exported <variables-export>`):
set -gx LANG de_DE.UTF-8

Если вы хотите установить какие-то персональные настройки, универсальные переменные хороши:

# Typically you'd run this interactively, fish takes care of keeping it.
set -U fish_color_autosuggestion 555

Следующий код ничего не выведет:

begin
    # This is a nice local scope where all variables will die
    set -l pirate 'There be treasure in them thar hills'
    set captain Space, the final frontier
end

echo $pirate
# This will not output anything, since the pirate was local
echo $captain
# This will output the good Captain's speech since $captain had function-scope.

Переопределение переменных для одной команды

Если вы хотите переопределить переменную для одной команды, вы можете использовать инструкции "var=val" перед командой:

# Call git status on another directory
# (can also be done via `git -C somerepo status`)
GIT_DIR=somerepo git status

Обратите внимание, что, в отличие от других оболочек, fish сначала установит переменную, а затем выполнит другие расширения в строке, поэтому:

set foo banana
foo=gagaga echo $foo # prints gagaga, while in other shells it might print "banana"

Несколько элементов могут быть заданы в расширении фигурных скобок:

# Call bash with a reasonable default path.
PATH={/usr,}/{s,}bin bash

Или с подстановкой по шаблону:

# Run vlc on all mp3 files in the current directory
# If no file exists it will still be run with no arguments
mp3s=*.mp3 vlc $mp3s

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

Этот синтаксис поддерживается начиная с fish 3.1.

Подробнее об универсальных переменных

Универсальные переменные — это переменные, которые используются во всех сессиях fish пользователя на компьютере. Fish хранит множество своих параметров конфигурации в виде универсальных переменных. Это означает, что для изменения настроек fish вам нужно изменить значение переменной только один раз, и оно будет автоматически обновлено для всех сессий и сохранится после перезагрузки компьютера и входа/выхода из системы.

Чтобы увидеть универсальные переменные в действии, запустите две сессии fish рядом, и выполните следующую команду в одной из них set fish_color_cwd blue. Поскольку fish_color_cwd — это универсальная переменная, цвет отображения текущей рабочей директории в приглашении мгновенно изменится на синий в обоих терминалах.

Универсальные переменные хранятся в файле .config/fish/fish_variables. Не редактируйте этот файл напрямую, так как ваши изменения могут быть перезаписаны. Редактируйте переменные с помощью скриптов fish или в интерактивном режиме.

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

Область видимости переменных для функций

При вызове функции все текущие локальные переменные временно исчезают. Это затемнение локальной области видимости необходимо, поскольку пространство имён переменных станет перегруженным, что сильно затруднит случайное перезапись переменных из другой функции.

Например:

function shiver
    set phrase 'Shiver me timbers'
end

function avast
    set --local phrase 'Avast, mateys'
    # Calling the shiver function here can not
    # change any variables in the local scope
    shiver
    echo $phrase
end
avast

# Outputs "Avast, mateys"

Экспорт переменных

Переменные в fish могут быть «экспортированы», поэтому они будут унаследованы любыми командами, запущенными fish. В частности, это необходимо для переменных, используемых для настройки внешних команд, таких как $LESS или $GOPATH, а также для переменных, содержащих общие системные настройки, такие как $PATH или $LANGUAGE. Если внешней команде нужна переменная, она должна быть экспортирована.

Это также относится к fish — при запуске она получает переменные среды от своего родительского процесса (обычно терминала). Обычно это включает в себя системную конфигурацию, такую как $PATH и переменные локали.

Переменные можно явно установить для экспорта с помощью переключателя -x или --export, или не экспортировать с помощью переключателя -u или --unexport. Правила экспорта при установке переменной идентичны правилам области видимости переменных:

  • Если переменная явно установлена для экспорта или не для экспорта, это значение будет соблюдаться.
  • Если переменная не явно установлена для экспорта или не для экспорта, но была определена ранее, предыдущее правило экспорта переменной сохраняется.
  • В противном случае по умолчанию переменная не будет экспортирована.
  • Если переменная имеет локальную область видимости и экспортирована, любая вызываемая функция получает копию ее значения, поэтому любые изменения, внесённые в переменную, исчезают после возврата функции.
  • Глобальные переменные доступны функциям независимо от того, экспортированы они или нет.

В соответствии с соглашением об именовании, экспортированные переменные записываются с заглавными буквами, а неэкспортированные — со строчными.

Например:

set -gx ANDROID_HOME ~/.android # /opt/android-sdk
set -gx CDPATH . ~ (test -e ~/Videos; and echo ~/Videos)
set -gx EDITOR emacs -nw
set -gx GOPATH ~/dev/go
set -gx GTK2_RC_FILES "$XDG_CONFIG_HOME/gtk-2.0/gtkrc"
set -gx LESSHISTFILE "-"

Примечание: Экспорт — это не область видимости, а дополнительное состояние. Обычно имеет смысл делать экспортированные переменные глобальными, но локально экспортированные переменные могут быть полезны, если вам нужно что-то более конкретное, чем Переопределения. Они копируются в функции, поэтому функция не может изменить их вне её, и остаются доступными для команд.

Списки

Fish может хранить список (или «массив», если хотите) нескольких строк внутри переменной:

> set mylist first second third
> printf '%s\n' $mylist # prints each element on its own line
first
second
third

Чтобы получить доступ к одному элементу списка, используйте индекс элемента в квадратных скобках, например:

echo $PATH[3]

Обратите внимание, что индексы списков начинаются с 1 в fish, а не с 0, как в других языках программирования. Это связано с тем, что требуется меньше вычитаний из 1, и многие общие утилиты Unix, такие как seq , работают лучше с таким способом (seq 5 выводит от 1 до 5, а не от 0 до 5). Неверный индекс игнорируется без сообщений об ошибках, что приводит к отсутствию значения (даже не пустая строка, а просто отсутствие аргумента).

Если вы не используете квадратные скобки, все элементы списка будут переданы команде как отдельные элементы. Это означает, что вы можете перебирать список с помощью for:

for i in $PATH
    echo $i is in the path
end

Это перебирает каждую директорию в $PATH отдельно и выводит строку, обозначающую, что она находится в пути.

Для создания переменной smurf, содержащей элементы blue и small, просто напишите:

set smurf blue small

Также возможно установить или удалить отдельные элементы списка:

# Set smurf to be a list with the elements 'blue' and 'small'
set smurf blue small

# Change the second element of smurf to 'evil'
set smurf[2] evil

# Erase the first element
set -e smurf[1]

# Output 'evil'
echo $smurf

Если вы указываете отрицательный индекс при расширении или присвоении значений переменной списка, индекс будет взят с конца списка. Например, индекс -1 — это последний элемент списка:

> set fruit apple orange banana
> echo $fruit[-1]
banana

> echo $fruit[-2..-1]
orange
banana

> echo $fruit[-1..1] # reverses the list
banana
orange
apple

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

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

Когда список экспортируется как переменная среды, он разграничивается пробелами или двоеточиями в зависимости от того, является ли это переменной пути:

> set -x smurf blue small
> set -x smurf_PATH forest mushroom
> env | grep smurf
smurf=blue small
smurf_PATH=forest:mushroom

Fish автоматически создаёт списки из всех переменных среды, имя которых заканчивается на PATH (например, $PATH, $CDPATH или $MANPATH), разделяя их двоеточиями. Другие переменные не разбиваются автоматически.

Списки можно просматривать с помощью команд count или contains:

count $smurf
# 2

contains blue $smurf
# key found, exits with status 0

> contains -i blue $smurf
1

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

set -l grep_args -r "my string"
grep $grep_args . # will run the same as `grep -r "my string"` .

В отличие от других оболочек, fish не выполняет «разделение слов» — элементы списка остаются такими, какие они есть, даже если они содержат пробелы или табуляции.

Обработка аргументов

Важным списком является $argv, содержащий аргументы функции или скрипта. Например:

function myfunction
    echo $argv[1]
    echo $argv[3]
end

Эта функция принимает все полученные аргументы и выводит первый и третий:

> myfunction first second third
first
third

> myfunction apple cucumber banana
apple
banana

Инструменты командной строки часто получают различные опции, флаги и позиционные аргументы, и $argv будет содержать все это.

Более надёжный подход к обработке аргументов — argparse, который проверяет заданные опции и помещает их в различные переменные, оставляя только позиционные аргументы в $argv. Вот простой пример:

function mybetterfunction
    argparse h/help s/second -- $argv
    or return # exit if argparse failed because it found an option it didn't recognize - it will print an error

    # If -h or --help is given, we print a little help text and return
    if set -q _flag_help
        echo "mybetterfunction [-h|--help] [-s|--second] [ARGUMENTS...]"
        return 0
    end

    # If -s or --second is given, we print the second argument,
    # not the first and third.
    if set -q _flag_second
        echo $argv[2]
    else
        echo $argv[1]
        echo $argv[3]
    end
end

Опции будут удалены из $argv, поэтому $argv[2] теперь является вторым позиционным аргументом:

> mybetterfunction first -s second third
second

Переменные PATH

Переменные PATH — это особый вид переменных, используемых для поддержки списков путей с разделителем двоеточие, включая PATH, CDPATH, MANPATH, PYTHONPATH и т. д. Все переменные, заканчивающиеся на «PATH» (регистрозависимые), становятся переменными PATH.

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

set MYPATH 1 2 3
echo "$MYPATH"
# 1:2:3
set MYPATH "$MYPATH:4:5"
echo $MYPATH
# 1 2 3 4 5
echo "$MYPATH"
# 1:2:3:4:5

Переменные можно отметить или отметать как переменные PATH с помощью опций --path и --unpath для set.

Специальные переменные

Вы можете изменить настройки fish, изменив значения определённых переменных.

  • PATH, список каталогов, в которых следует искать команды
  • CDPATH, список каталогов, в которых встроенная команда cd ищет новый каталог.
  • Переменные локали LANG, LC_ALL, LC_COLLATE, LC_CTYPE, LC_MESSAGES, LC_MONETARY, LC_NUMERIC и LC_TIME задают языковой параметр для оболочки и подпрограмм. Подробнее см. раздел Переменные локали.
  • Несколько переменных, начинающихся с префиксов fish_color и fish_pager_color. Подробнее см. Переменные для изменения цветов выделения.
  • fish_ambiguous_width управляет вычисляемой шириной символов с неоднозначной шириной. Она должна быть установлена в 1, если ваша терминальная программа отображает такие символы как символы одинарной ширины (обычно), или в 2, если символы двойной ширины.
  • fish_emoji_width управляет тем, считает ли fish, что эмодзи отображаются как символы шириной в 2 клетки или 1 клетку. Это необходимо, потому что правильное значение изменилось с 1 на 2 в Unicode 9, и некоторые терминальные программы могут об этом не знать. Установите это значение, если вы видите графические артефакты, связанные с эмодзи (или другими «специальными» символами). Обычно это значение определяется автоматически.
  • FISH_DEBUG и FISH_DEBUG_OUTPUT управляют тем, какой отладочный вывод генерирует fish и куда его помещает, аналогично параметрам --debug и --debug-output. Эти параметры должны быть установлены при запуске, например, через FISH_DEBUG='reader*' FISH_DEBUG_OUTPUT=/tmp/fishlog fish.
  • fish_escape_delay_ms определяет, сколько времени fish ждет нажатия другой клавиши после получения escape-последовательности, чтобы отличить нажатие клавиши escape от начала escape-последовательности. По умолчанию — 30 мс. Увеличение этого значения увеличивает задержку, но позволяет нажимать escape вместо alt для назначений alt+символ. Подробнее см. главу в документации bind.
  • fish_greeting, приветственное сообщение, выводимое при запуске. Оно выводится функцией с тем же названием, которую можно переопределить для более сложных изменений (см. funced
  • fish_handle_reflow, определяет, должна ли fish пытаться перерисовать командную строку при изменении размеров терминала. В терминалах, которые переформатируют текст, это следует отключить. Установите значение 1, чтобы включить, любое другое значение — чтобы отключить.
  • fish_history, имя текущей сессии истории. Если установлено, все последующие команды в интерактивной сессии fish будут регистрироваться в отдельном файле, имя которого определяется значением переменной. Если не установлено или установлено в default, используется имя сессии по умолчанию «fish». Если установлено в пустую строку, история не сохраняется на диск (но всё ещё доступна в интерактивной сессии).
  • fish_trace, если установлено и не пусто, заставит fish выводить команды перед их выполнением, подобно set -x в bash. Трассировка выводится в путь, указанный параметром --debug-output для fish (по умолчанию в stderr).
  • fish_user_paths, список каталогов, которые добавляются перед PATH . Это может быть универсальная переменная.
  • umask, текущая маска создания файлов. Предпочтительный способ изменения переменной umask — через функцию umask. Попытка установить umask в недопустимое значение всегда завершится неудачей.
  • BROWSER, ваш предпочтительный веб-браузер. Если эта переменная установлена, fish будет использовать указанный браузер вместо системного браузера по умолчанию для отображения документации fish.

Fish также предоставляет дополнительную информацию через значения определённых переменных среды. Большинство этих переменных являются только для чтения, и их значение нельзя изменить с помощью set.

  • _, имя текущей выполняемой команды (хотя это устарело, и предпочтительно использовать status current-command).
  • argv, список аргументов для оболочки или функции. argv определена только при вызове функции или если fish был вызван со списком аргументов, например, fish myscript.fish foo bar. Эту переменную можно изменить.
  • CMD_DURATION, время выполнения последней команды в миллисекундах.
  • COLUMNS и LINES, текущий размер терминала по высоте и ширине. Эти значения используются fish только если операционная система не сообщает размер терминала. В таком случае обе переменные должны быть установлены, иначе используется значение по умолчанию 80x24. Они обновляются при изменении размера окна.
  • fish_kill_signal, сигнал, который завершил последний фоновый процесс, или 0, если процесс завершился нормально.
  • fish_pid, идентификатор процесса (PID) оболочки.
  • history, список последних введённых команд.
  • HOME, домашний каталог пользователя. Эту переменную можно изменить.
  • hostname, имя хоста машины.
  • IFS, внутренний разделитель полей, который используется для разделения слов с помощью встроенной команды read. Установка этого значения в пустую строку также отключит разделение строк в замене команд. Эту переменную можно изменить.
  • last_pid, идентификатор процесса (PID) последнего фонового процесса.
  • PWD, текущий рабочий каталог.
  • pipestatus, список кодов завершения всех процессов, составляющих последнюю выполненную трубу.
  • SHLVL, уровень вложенности оболочек.
  • status, код завершения последнего завершившегося фонового процесса. Если процесс завершился по сигналу, код завершения будет равен 128 плюс номер сигнала.
  • status_generation, счётчик «поколения» для $status. Он увеличивается только тогда, когда предыдущая команда произвела явный код состояния. (Например, фоновые процессы не будут увеличивать его).
  • USER, текущее имя пользователя. Эту переменную можно изменить.
  • version, версия текущей работающей fish (также доступна как FISH_VERSION для обратной совместимости).

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

Fish также использует некоторые переменные внутри, имена которых обычно начинаются с __fish. Эти переменные являются внутренними и обычно не должны изменяться напрямую.

Переменная статуса

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

Fish сохраняет код завершения последнего завершившегося процесса в переменной status.

Если fish сталкивается с проблемой при выполнении команды, переменная статуса также может быть установлена в определённое значение:

  • 0 — обычно код завершения команд fish, если они успешно выполнили запрошенную операцию.
  • 1 — обычно код завершения команд fish, если они не смогли выполнить запрошенную операцию.
  • 121 — обычно код завершения команд fish, если им были переданы неверные аргументы.
  • 123 — значит, команда не была выполнена, потому что имя команды содержало недопустимые символы.
  • 124 — значит, команда не была выполнена, потому что ни один из шаблонов в имени команды не дал совпадений.
  • 125 — значит, что хотя исполняемый файл с указанным именем был найден, операционная система не смогла выполнить команду.
  • 126 — значит, что хотя файл с указанным именем был найден, он не был исполняемым.
  • 127 — значит, что ни функция, ни встроенная команда, ни команда с данным именем не были найдены.

Если процесс завершается по сигналу, код завершения будет равен 128 плюс номер сигнала.

Переменные подсветки синтаксиса

Цвета, используемые fish для подсветки синтаксиса, можно настроить, изменив значения различных переменных. Значение этих переменных может быть одним из цветов, принятых командой set_color. Также принимаются переключатели --bold или -b, принятые командой set_color.

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

set fish_color_error red --bold

Следующие переменные доступны для изменения цветов подсветки в fish:

Переменная Значение
fish_color_normal цвет по умолчанию
fish_color_command команды типа echo
fish_color_keyword ключевые слова, типа if — в случае отсутствия, используется цвет команды
fish_color_quote строки в кавычках, типа "abc"
fish_color_redirection перенаправление ввода/вывода, типа >/dev/null
fish_color_end разделители процессов, типа ';' и '&'
fish_color_error синтаксические ошибки
fish_color_param обычные параметры команд
fish_color_comment комментарии, типа '# важное сообщение'
fish_color_selection выделенный текст в режиме визуального редактирования vi
fish_color_operator операторы расширения параметров, типа '*' и '~'
fish_color_escape экранирование символов, типа 'n' и 'x70'
fish_color_autosuggestion автозаполнение (предлагаемая оставшаяся часть команды)
fish_color_cwd текущая рабочая директория в приглашении по умолчанию
fish_color_user имя пользователя в приглашении по умолчанию
fish_color_host имя хоста в приглашении по умолчанию
fish_color_host_remote имя хоста в приглашении по умолчанию для удалённых сессий (например, ssh)
fish_color_cancel индикатор '^C' при отмене команды
fish_color_search_match соответствия при поиске по истории и выбранные элементы в просмотрщике (только фон)

Переменные цвета просмотрщика

fish иногда отображает список вариантов в таблице, называемой просмотрщиком.

Пример: для установки фона каждой строки просмотрщика используйте:

set fish_pager_color_background --background=white

Для отображения чёрного текста на чередующихся белых и серых фонах:

set fish_pager_color_prefix black
set fish_pager_color_completion black
set fish_pager_color_description black
set fish_pager_color_background --background=white
set fish_pager_color_secondary_background --background=brwhite

Переменные, влияющие на цвета просмотрщика:

Переменная Значение
fish_pager_color_progress строка прогресса в левом нижнем углу
fish_pager_color_background цвет фона строки
fish_pager_color_prefix строка префикса, т.е. строка, которая должна быть дополнена
fish_pager_color_completion само дополнение, т.е. предлагаемая оставшаяся часть строки
fish_pager_color_description описание дополнения
fish_pager_color_selected_background фон выбранного дополнения
fish_pager_color_selected_prefix префикс выбранного дополнения
fish_pager_color_selected_completion суффикс выбранного дополнения
fish_pager_color_selected_description описание выбранного дополнения
fish_pager_color_secondary_background фон каждой второй невыбранной строки дополнения
fish_pager_color_secondary_prefix префикс каждой второй невыбранной строки дополнения
fish_pager_color_secondary_completion суффикс каждой второй невыбранной строки дополнения
fish_pager_color_secondary_description описание каждой второй невыбранной строки дополнения

Переменные локали

«Локаль» программы — это её набор языковых и региональных настроек. В UNIX есть несколько отдельных переменных для управления разными аспектами — LC_CTYPE определяет кодировку текста, а LC_TIME — формат времени.

Переменные локали: LANG, LC_ALL, LC_COLLATE, LC_CTYPE, LC_MESSAGES, LC_MONETARY, LC_NUMERIC и LC_TIME. Эти переменные работают следующим образом: LC_ALL принудительно устанавливает все аспекты локали указанному значению. Если установлена LC_ALL, все остальные переменные локали будут проигнорированы (обычно это не рекомендуется!). Другие LC_ переменные устанавливают указанный аспект информации о локали. LANG — значение по умолчанию, оно будет использоваться, если ни одна из LC_ переменных не указана.

Наиболее распространённый способ установки локали — использование команды, такой как set -gx LANG en_GB.utf8, которая устанавливает текущую локаль на английский язык, используемый в Великобритании, с набором символов UTF-8. Таким образом, любая программа, требующая другого значения, может легко его переопределить, а не прибегать к LC_ALL. Список доступных локалей на вашей системе можно получить, выполнив команду locale -a.

Встроенные команды

Fish содержит ряд команд, непосредственно встроенных в оболочку. Мы называем их «встроенными». К ним относятся:

  • Встроенные команды для управления состоянием оболочки — cd для изменения директории, set для установки переменных
  • Встроенные команды для работы с данными, такие как string для строк и math для чисел, count для подсчёта строк или аргументов
  • status для запроса состояния оболочки
  • printf и echo для создания вывода
  • test для проверки условий
  • argparse для парсинга аргументов функций
  • source для чтения скрипта в текущей оболочке (изменения переменных останутся) и eval для выполнения строки как скрипта
  • random для получения случайных чисел или выбора случайного элемента из списка

Список всех встроенных команд можно получить, выполнив builtin -n.

Список всех встроенных команд, функций и команд, поставляемых с fish, см. в списке команд. Документация также доступна с помощью переключателя --help.

Имена переменных и функций оболочки

Имена переменных и функций (также называемые «идентификаторами») должны соответствовать определённым правилам:

  • Имя переменной не может быть пустым. Оно может содержать только буквы, цифры и символы нижнего подчёркивания. Оно может начинаться и заканчиваться любым из этих символов.
  • Имя функции не может быть пустым. Оно не может начинаться с дефиса («-») и не может содержать слэша («/»). Все остальные символы, включая пробелы, допустимы.
  • Имя режима привязки (например, bind -m abc ...) должно быть допустимым именем переменной.

Другие вещи имеют другие ограничения. Например, то, что разрешено для имён файлов, зависит от вашей системы, но по крайней мере они не могут содержать слэш («/» — это разделитель пути) или нулевой байт (так UNIX завершает строки).

Интерактивное использование

Fish гордится тем, что очень удобен в интерактивном режиме. Это достигается благодаря нескольким особенностям, которые будут объяснены в следующих разделах.

Справка

Fish обладает обширной системой справки. Используйте команду help для получения справки по определённой теме или команде. Например, написание help syntax отобразит раздел «Синтаксис» этой документации.

Fish также имеет страницы man для своих команд и переводит страницы справки в страницы man. Например, man set отобразит документацию по set в виде страницы man.

Справку по конкретной встроенной команде можно получить с параметром -h. Например, чтобы получить справку по встроенной команде fg, введите fg -h или help fg.

Данную страницу можно просмотреть с помощью help index (или просто help) или man fish-doc . Руководство можно просмотреть с помощью help tutorial или man fish-tutorial.

Автозаполнение

fish предлагает команды по мере ввода, основываясь на истории команд, завершении и допустимых путях к файлам. При вводе команд вы увидите предложение после курсора в приглушённо-сером цвете (цвет можно изменить с помощью переменной fish_color_autosuggestion).

Для принятия автозаполнения (заменяющего содержимое командной строки) нажмите → или Control+F. Чтобы принять первое предложенное слово, нажмите Alt+→ или Alt+F. Если автозаполнение вам не подходит, просто проигнорируйте его: оно не будет выполнено, пока вы его не примете.

Автозаполнение — мощный способ быстро вызывать часто используемые команды, набрав несколько первых символов. Это также эффективный способ перемещения по иерархии каталогов.

Автодополнение с Tab

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

Для навигации по страницам можно использовать стрелки, Page Up / Page Down, Tab или Shift+Tab. Нажатие Control+S (привязка pager-toggle-search — / в режиме vi) открывает меню поиска, которое можно использовать для фильтрации списка.

Fish предоставляет некоторые общенаправленные дополнения:

  • Команды (встроенные, функции и обычные программы).
  • Имена переменных оболочки.
  • Имена пользователей для расширения тильды.
  • Имена файлов, даже в строках с подстановкой символов, таких как * и **.

Он также предоставляет большое количество специфических для программы запрограммированных дополнений. Большинство из этих дополнений — простые варианты, такие как параметр -l для ls, но некоторые более сложные. Например:

  • Программы man и whatis отображают все установленные страницы руководства в качестве дополнений.
  • Программа make использует все цели в файле Makefile в текущем каталоге в качестве дополнений.
  • Команда mount использует все точки монтирования, указанные в файле fstab, в качестве дополнений.
  • Команда ssh использует все хосты, которые хранятся в файле known_hosts, в качестве дополнений. (См. документацию ssh для получения дополнительной информации)
  • Команда su отображает пользователей в системе.
  • Команды apt-get, rpm и yum отображают установленные или устанавливаемые пакеты.

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

Выделение синтаксиса

Fish интерпретирует командную строку по мере её ввода и использует выделение синтаксиса для предоставления обратной связи. Самой важной обратной связью является обнаружение потенциальных ошибок. По умолчанию ошибки отмечаются красным цветом.

Обнаруженные ошибки включают:

  • Отсутствующие команды.
  • Чтение из или добавление в несуществующий файл.
  • Неправильное использование перенаправления вывода.
  • Несоответствующие скобки.

Когда курсор находится над скобкой или кавычкой, fish также выделяет соответствующую кавычку или скобку.

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

Сокращения

Чтобы избежать ненужного ввода, часто используемую команду, такую как git checkout, можно сократить до gco с помощью команды abbr.

abbr -a gco git checkout

После ввода gco и нажатия Space или Enter в командной строке появится полный текст git checkout.

Это альтернатива псевдонимам и имеет преимущество, что вы видите фактическую команду перед её использованием, и фактическая команда будет сохранена в истории.

Настраиваемое заголовок

При использовании большинства виртуальных терминалов можно установить сообщение, отображаемое в строке заголовка окна терминала. Это можно сделать автоматически в fish, определив функцию fish_title. Функция fish_title выполняется до и после выполнения новой команды или её перевода в фоновый режим, а вывод используется в качестве сообщения строки заголовка. Встроенная команда status current-command всегда возвращает имя задания, которое должно быть переведено в фоновый режим (или fish при возвращении управления в оболочку) при вызове функции fish_prompt <cmd-fish_prompt>. Первый аргумент функции fish_title будет содержать самую последнюю выполненную команду в фоновом режиме как строку, начиная с fish 2.2.

Примеры: По умолчанию заголовок fish:

function fish_title
    echo (status current-command) ' '
    pwd
end

Чтобы отобразить последнюю команду в заголовке:

function fish_title
    echo $argv[1]
end

Настраиваемый приглашение

Когда fish ожидает ввода, он отобразит приглашение, оценив функции fish_prompt и fish_right_prompt. Вывод первой отображается слева, а вывод последней — справа от терминала. Вывод fish_mode_prompt будет добавлен слева, хотя функция по умолчанию делает это только при работе в режиме vi.

Настраиваемое приветствие

Если существует функция с именем fish_greeting, она будет запущена при входе в интерактивный режим. В противном случае, если существует переменная окружения с именем fish_greeting, она будет напечатана.

Режим приватности

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

Вы также можете запустить с fish --private (или fish -P для краткости). Это скрывает старую историю и предотвращает запись истории на диск. Это полезно для предотвращения утечки личной информации (например, при записи скриншотов) или при работе со конфиденциальной информацией.

Вы можете запросить переменную fish_private_mode (if set -q fish_private_mode ...), если хотите учесть пожелания пользователя о конфиденциальности и изменить поведение собственных скриптов fish.

Редактор командной строки

Редактор fish поддерживает копирование и вставку, поисковую историю и множество функций редактора, которые можно привязать к специальным сочетаниям клавиш.

Аналогично bash, fish имеет режимы редактирования Emacs и Vi. Режим редактирования по умолчанию — Emacs. Можно переключиться в режим Vi с fish_vi_key_bindings и вернуться обратно с fish_default_key_bindings. Вы также можете создать свои собственные сочетания клавиш, создав функцию и установив $fish_key_bindings в её имя. Например:

function fish_hybrid_key_bindings --description \
"Vi-style bindings that inherit emacs-style bindings in all modes"
    for mode in default insert visual
        fish_default_key_bindings -M $mode
    end
    fish_vi_key_bindings --no-erase
end
set -g fish_key_bindings fish_hybrid_key_bindings

Общие привязки

Некоторые привязки общие для режимов emacs и vi, потому что они не привязки к редактированию текста или потому что то, что делает Vi/Vim для определённой клавиши, не имеет смысла для оболочки.

  • Tab завершает текущий токен. Shift+Tab завершает текущий токен и запускает режим поиска утилиты просмотра.
  • ← (влево) и → (вправо) перемещают курсор влево или вправо на один символ. Если курсор уже находится в конце строки, а доступна автоподсказка, то → принимает автоподсказку.
  • Alt+← и Alt+→ перемещают курсор влево или вправо на одно слово (до следующего пробела или знака препинания), или перемещают вперёд/назад в истории команд, если командная строка пуста. Если курсор уже находится в конце строки, и доступна автоподсказка, то Alt+→ (или Alt+F) принимает первое слово в подсказке.
  • Control+← и Control+→ перемещают курсор влево или вправо на одно слово. Они принимают одно слово автоподсказки — часть, над которой они перемещаются.
  • Shift+← и Shift+→ перемещают курсор влево или вправо на одно слово, не останавливаясь на знаках препинания. Они принимают одно большое слово из автоподсказки.
  • ↑ (вверх) и ↓ (вниз) (или Control+P и Control+N для любителей Emacs) ищут в истории команд предыдущую/следующую команду, содержащую строку, указанную в командной строке до начала поиска. Если командная строка была пустой в начале поиска, все команды подходят. Дополнительную информацию о поиске в истории см. в разделе история.
  • Alt+↑ и Alt+↓ ищут в истории команд предыдущий/следующий токен, содержащий токен под курсором до начала поиска. Если командная строка не была на токене в начале поиска, все токены подходят. Дополнительную информацию о поиске в истории см. в разделе истории.
  • Control+C отменяет всю строку.
  • Control+D удаляет один символ справа от курсора. Если командная строка пуста, Control+D выведет из fish.
  • Control+U перемещает содержимое от начала строки до курсора в буфер обмена.
  • Control+L очищает и перерисовывает экран.
  • Control+R ищет в истории, если в командной строке есть что-то. Это в основном облегчает переход из других оболочек, где ctrl+r инициирует поиск в истории.
  • Control+W перемещает предыдущий компонент пути (все до предыдущего "/", ":" или "@") в буфер обмена.
  • Control+X копирует текущий буфер в буфер обмена системы, Control+V вставляет содержимое буфера обмена.
  • Alt+D перемещает следующее слово в буфер обмена.
  • Alt+H (или F1) отображает страницу справки для текущей команды, если она существует.
  • Alt+L выводит содержимое текущей директории, если курсор не стоит над аргументом директории, в противном случае выводится содержимое этой директории.
  • Alt+O открывает файл по курсору в утилите просмотра.
  • Alt+P добавляет строку &| less; в конец задачи под курсором. Результатом является то, что вывод команды будет просматриваться.
  • Alt+W выводит краткое описание команды под курсором.
  • Alt+E редактирует текущую командную строку в внешнем редакторе. Редактор выбирается из первого доступного из переменных $VISUAL или $EDITOR.
  • Alt+V То же самое, что Alt+E.
  • Alt+S Добавляет sudo в начало текущей командной строки. Если командная строка пустая, добавляет sudo в начало последней командной строки.
  • Control+Space Вставляет пробел без развёртывания аббревиатуры. Для режима vi это относится только к режиму вставки.

Команды режима Emacs

  • Home или Control+A перемещает курсор в начало строки.
  • End или Control+E перемещает курсор в конец строки. Если курсор уже находится в конце строки, а доступна автоподсказка, то End или Control+E принимает автоподсказку.
  • Control+B, Control+F перемещают курсор на один символ влево или вправо или принимают автоподсказку, как и общие сочетания клавиш ← (влево) и → (вправо) (которые также доступны).
  • Control+N, Control+P перемещают курсор вверх/вниз или по истории, как и общие сочетания клавиш стрелок вверх и вниз.
  • Delete или Backspace удаляет по одному символу вперёд или назад соответственно.
  • Control+K перемещает содержимое от курсора до конца строки в буфер обмена.
  • Alt+C преобразует текущее слово в верхний регистр.
  • Alt+U преобразует текущее слово в верхний регистр.
  • Control+T меняет местами последние два символа.
  • Alt+T меняет местами последние два слова.
  • Control+Z, Control+_ (Control+/ на некоторых терминалах) отменяет последнее изменение в строке.
  • Alt+/ отменяет последнюю отмену.

Эти сочетания клавиш можно изменить с помощью встроенной команды bind.

Команды режима Vi

Режим Vi позволяет использовать команды, похожие на Vi, в командной строке. Изначально активен режим вставки insert mode. Escape переключает на режим команд. Команды, доступные в режимах команд, вставки и визуального режима, описаны ниже. Режим Vi использует некоторые сочетания клавиш из режима Emacs.

Также можно добавить все сочетания клавиш из режима Emacs в режим Vi, используя что-то вроде:

function fish_user_key_bindings
    # Execute this once per mode that emacs bindings should be used in
    fish_default_key_bindings -M insert

    # Then execute the vi-bindings so they take precedence when there's a conflict.
    # Without --no-erase fish_vi_key_bindings will default to
    # resetting all bindings.
    # The argument specifies the initial mode (insert, "default" or visual).
    fish_vi_key_bindings --no-erase insert
end

При работе в режиме vi, функция fish_mode_prompt будет отображать индикатор режима слева от подсказки. Чтобы отключить эту функцию, переопределите её пустой функцией. Чтобы отобразить режим в другом месте (например, в правой подсказке), используйте вывод функции fish_default_mode_prompt.

Когда команда изменяет режим, она перерисует подсказку режима, если она существует, а остальную часть подсказки только если она не существует. Таким образом, если вам нужен индикатор режима в вашей fish_prompt, вам нужно стереть fish_mode_prompt, например, добавив пустой файл в ~/.config/fish/functions/fish_mode_prompt.fish. (Команды, которые изменяют режим, должны вызывать функцию привязки repaint-mode, см. bind)

Функция fish_vi_cursor будет использоваться для изменения формы курсора в зависимости от режима в поддерживаемых терминалах. Следующий фрагмент кода можно использовать для ручного настройки курсора после включения режима vi:

# Emulates vim's cursor shape behavior
# Set the normal and visual mode cursors to a block
set fish_cursor_default block
# Set the insert mode cursor to a line
set fish_cursor_insert line
# Set the replace mode cursor to an underscore
set fish_cursor_replace_one underscore
# The following variable can be used to configure cursor shape in
# visual mode, but due to fish_cursor_default, is redundant here
set fish_cursor_visual block

Кроме того, blink можно добавить после каждого из параметров формы курсора, чтобы установить мигающий курсор в указанной форме.

Если форма курсора не меняется после установки вышеперечисленных переменных, вероятно, ваш терминальный эмулятор не поддерживает необходимые возможности для этого. Возможно также, что fish_vi_cursor неверно определил возможности вашего терминала (например, если вы используете tmux). В этом случае вы можете принудительно установить форму курсора, задав $fish_vi_force_cursor в config.fish. Вам придётся перезапустить fish, чтобы изменения вступили в силу. Если настройка формы курсора остаётся неисправной после этого, это почти наверняка проблема с вашим терминальным эмулятором, а не с fish.

Режим команды

Режим команды также известен как нормальный режим.

  • H перемещает курсор влево.
  • L перемещает курсор вправо.
  • I переходит в режим вставки в текущей позиции курсора.
  • V переходит в режим визуального выбора в текущей позиции курсора.
  • A переходит в режим вставки после текущей позиции курсора.
  • Shift+A переходит в режим вставки в конце строки.
  • 0 (ноль) перемещает курсор к началу строки (оставаясь в режиме команды).
  • D+D удаляет текущую строку и перемещает её в буфер обмена.
  • Shift+D удаляет текст после текущей позиции курсора и перемещает его в буфер обмена.
  • P вставляет текст из буфера обмена.
  • U просматривает историю команд в обратном порядке.
  • [ и ] ищут в истории команд предыдущий/следующий элемент, содержащий текущий элемент под курсором до начала поиска. См. раздел истории для получения дополнительной информации о поиске в истории.
  • Backspace перемещает курсор влево.

Режим вставки

  • Escape переходит в режим команды.
  • Backspace удаляет один символ слева.

Режим визуального выбора

  • ← (влево) и → (вправо) расширяют выделение назад/вперед на один символ.
  • B и W расширяют выделение назад/вперед на одно слово.
  • D и X перемещают выделение в буфер обмена и переходят в режим команды.
  • Escape и Control+C переходят в режим команды.

Настраиваемые привязки

В дополнение к стандартным привязки, описанным здесь, вы можете определить свои собственные с помощью bind:

# Just clear the commandline on control-c
bind \cc 'commandline -r ""'

Поместите bind в config.fish или функцию, названную fish_user_key_bindings.

Последовательность нажатий клавиш (\cc) зависит от вашей конфигурации, в частности от терминала. Чтобы узнать, что отправляет терминал, используйте fish_key_reader:

> fish_key_reader # pressing control-c
Press a key:
            hex:    3  char: \cC
Press [ctrl-C] again to exit
bind \cC 'do something'

> fish_key_reader # pressing the right-arrow
Press a key:
            hex:   1B  char: \c[  (or \e)
(  0.077 ms)  hex:   5B  char: [
(  0.037 ms)  hex:   43  char: C
bind \e\[C 'do something'

Обратите внимание, что некоторые комбинации клавиш неразличимы или непереопределяемы. Например, сочетание клавиш Control-i эквивалентно клавише Tab. Это ограничение терминала, и fish ничего не может с этим сделать.

Также, Escape эквивалентно Alt в терминале. Чтобы различить нажатие Escape и затем другой клавиши, и нажатие Alt и этой клавиши (или последовательности, которую отправляет клавиша), fish ожидает определённого времени после получения символа Escape. Это настраивается через переменную fish_escape_delay_ms.

Если вы хотите, чтобы нажатие Escape, а затем символа считалось как Alt+этим символом, установите значение переменной выше, например:

set -g fish_escape_delay_ms 100

Копирование и вставка (Буфер обмена)

Fish использует буфер обмена в стиле Emacs для копирования и вставки. Например, используйте Control+K (kill-line) для вырезания от текущей позиции курсора до конца строки. Строка, которая вырезается (в emacs-терминах, "убивается"), добавляется в список вырезанных фрагментов, называемый буфером обмена. Для вставки последнего значения из буфера обмена (в emacs это называется "вытащить") используйте Control+Y (функция ввода yank). После вставки используйте Alt+Y (yank-pop) для перехода к предыдущему элементу буфера обмена.

Поддержка копирования и вставки извне также реализована, как через привязки Control+X / Control+V (функции fish_clipboard_copy и fish_clipboard_paste [7]), так и через функцию вставки терминала, для которой fish включает режим "Вставка с скобками", чтобы отличать вставку от ввода текста вручную. Кроме того, при вставке внутри одинарных кавычек вставленные одинарные кавычки и обратные слэши автоматически экранируются, так что результат может использоваться как один токен, просто закрыв кавычку после.

[7] Эти функции используют внешние инструменты. В настоящее время поддерживаются xsel, xclip, wl-copy/wl-paste и pbcopy/pbpaste.

Редактирование многострочных команд

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

  • Нажатие клавиши Enter в то время, когда блок команд не закрыт, например, когда одна или несколько команд блоков, такие как for, begin или if, не имеют соответствующей команды end.
  • Нажатие Alt+Enter вместо нажатия клавиши Enter.
  • Вставка символа обратного слэша (\) перед нажатием клавиши Enter для экранирования символа новой строки.

Редактор командной строки fish работает абсолютно одинаково в однострочном и многострочном режимах. Для перемещения между строками используйте клавиши со стрелками и другие подобные сочетания клавиш.

Поиск в истории команд

После выполнения команды она запоминается в списке истории. Все дублируемые элементы истории автоматически удаляются. С помощью клавиш со стрелками вверх и вниз можно просматривать историю вперёд и назад. Если строка текущей команды не пуста при запуске поиска в истории, отображаются только те команды, которые содержат введённую строку.

Нажатие Alt+↑ и Alt+↓ также выполняет поиск в истории, но вместо поиска по всей команде, каждая команда разбивается на отдельные элементы, как и перед выполнением, и история просматривается на предмет совпадения с элементом под курсором.

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

Представление команды с пробела предотвратит сохранение всей строки в истории.

END_OF_DOCUMENT_MARKER

Журнал команд по умолчанию хранится в файле ~/.local/share/fish/fish_history (или $XDG_DATA_HOME/fish/fish_history, если эта переменная задана). Однако вы можете установить переменную окружения fish_history, чтобы изменить имя сессии истории (в результате чего будет создан файл <session>_history); это можно сделать как перед запуском оболочки, так и во время её работы.

См. команду history для других операций.

Примеры:

Чтобы найти предыдущие записи, содержащие слово «make», введите make в консоли и нажмите клавишу вверх.

Если в командной строке отображается cd m, поместите курсор на символ m и нажмите Alt+↑, чтобы найти ранее введённые слова, содержащие «m».

Перемещение по каталогам

Текущий рабочий каталог можно отобразить с помощью команды pwd или специальной переменной $PWD специальная переменная.

Журнал каталогов

Fish автоматически сохраняет историю посещённых каталогов с помощью команды cd, сохраняя эту историю в переменных dirprev и dirnext.

Предоставлены несколько команд для работы с этой историей каталогов:

  • dirh отображает историю
  • cdh выводит подсказку для быстрого перемещения по истории
  • prevd перемещается назад по истории. Она привязана к Alt+←
  • nextd перемещается вперёд по истории. Она привязана к Alt+→

Стек каталогов

Другой набор команд, обычно также доступный в других оболочках, таких как bash, работает со стеком каталогов. Управление стеком не автоматическое и требует явного вызова следующих команд:

  • dirs выводит стек
  • pushd добавляет каталог в верхнюю часть стека и делает его текущим рабочим каталогом
  • popd удаляет каталог с вершины стека и изменяет текущий рабочий каталог

Файлы инициализации

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

Файлы конфигурации оцениваются в следующем порядке:

  • Конфигурация, поставляемая с Fish, которую не следует редактировать, в $__fish_data_dir/config.fish (обычно /usr/share/fish/config.fish).
  • Фрагменты конфигурации в файлах, заканчивающихся на .fish, в каталогах:

    • $__fish_config_dir/conf.d (по умолчанию ~/.config/fish/conf.d/)
    • $__fish_sysconf_dir/conf.d (по умолчанию /etc/fish/conf.d/)
    • Каталоги для поставщиков стороннего программного обеспечения, чтобы они поставляли свои собственные фрагменты конфигурации для своего программного обеспечения. Fish ищет каталоги в переменной окружения XDG_DATA_DIRS для каталога fish/vendor_conf.d; если эта переменная не определена, по умолчанию выполняется поиск в /usr/share/fish/vendor_conf.d и /usr/local/share/fish/vendor_conf.d.

    Если в этих каталогах существует несколько файлов с одинаковым именем, будет выполнен только первый. Они выполняются в порядке их имени файла, отсортированные (как шаблоны) в естественном порядке (т.е. "01" сортируется раньше "2").

  • Системные файлы конфигурации, где администраторы могут включать инициализацию, которая должна выполняться для всех пользователей системы — аналогично /etc/profile для оболочек в стиле POSIX — в $__fish_sysconf_dir (обычно /etc/fish/config.fish).
  • Инициализация пользователя, обычно в ~/.config/fish/config.fish (управляется переменной окружения XDG_CONFIG_HOME, и доступна как $__fish_config_dir).

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

Этот широкий поиск может быть запутанным. Если вы не уверены, куда поместить свои собственные настройки, используйте ~/.config/fish/config.fish.

Обратите внимание, что ~/.config/fish/config.fish выполняется after фрагментами. Это делается для того, чтобы пользователи могли копировать фрагменты и переопределять их поведение.

Все эти файлы выполняются при запуске каждой оболочки. Если вы хотите выполнить команду только при запуске интерактивной оболочки, используйте код возврата команды status --is-interactive для определения того, является ли оболочка интерактивной. Если вы хотите выполнить команду только при использовании оболочки входа, используйте status --is-login вместо этого. Это ускорит запуск неинтерактивных или нелогиновых оболочек.

Если вы разрабатываете другую программу, вы можете захотеть установить конфигурацию, которая выполняется для всех пользователей оболочки fish в системе. Это не рекомендуется; если она не написана осторожно, она может иметь побочные эффекты или замедлять запуск оболочки. Кроме того, пользователи других оболочек не получат выгоды от конфигурации Fish. Однако, если они абсолютно необходимы, вы можете установить их в каталог конфигурации «vendor». Поскольку этот путь может отличаться от системы к системе, для обнаружения этого пути с помощью вывода pkg-config --variable confdir fish следует использовать фреймворк pkgconfig.

Примеры:

Если вы хотите добавить каталог ~/linux/bin в переменную PATH при использовании оболочки входа, добавьте следующее в свой файл ~/.config/fish/config.fish:

if status --is-login
    set -gx PATH $PATH ~/linux/bin
end

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

function on_exit --on-event fish_exit
    echo fish is now exiting
end

Будущие флаги функций

Флаги функций — это способ, с помощью которого fish внедряет изменения, которые могут сломать скрипты. Нарушающие изменения вводятся как опциональные, в течение нескольких релизов они становятся обязательными, а в конечном итоге старое поведение удаляется.

Вы можете посмотреть текущий список функций с помощью status features:

> status features
stderr-nocaret  on     3.0      ^ no longer redirects stderr
qmark-noglob    off    3.0      ? no longer globs
regex-easyesc   off    3.1      string replace -r needs fewer \\'s

В Fish 3.0 есть два нарушения: символ каретки ^ больше не перенаправляет stderr, и вопросительный знак ? больше не является шаблоном.

В Fish 3.1 есть одно нарушение: string replace -r выполняет излишний этап экранирования для замены, поэтому экранирование обратных слэшей выглядит как string replace -ra '([ab])' '\\\\\\\$1' a. Этот флаг удаляет это, если он включен, поэтому '\\\\$1' достаточно.

Эти изменения отключены по умолчанию. Их можно включить для текущей сессии:

> fish --features qmark-noglob,stderr-nocaret

или включить их глобально для пользователя:

> set -U fish_features stderr-nocaret qmark-noglob

Функции будут устанавливаться только при запуске, поэтому эта переменная будет действовать только если она является универсальной или экспортированной.

Вы также можете использовать версию как группу, поэтому 3.0 эквивалентно «stderr-nocaret» и «qmark-noglob».

Добавление префикса no- к функции отключает её.

Обработчики событий

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

  • При получении сигнала
  • При завершении процесса
  • При обновлении значения переменной
  • При отображении подсказки

Пример:

Для указания обработчика сигнала для сигнала WINCH напишите:

function my_signal_handler --on-signal WINCH
    echo Got WINCH signal!
end

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

Дополнительную информацию о определении новых обработчиков событий см. в документации команды function.

Отладка скриптов fish

Fish включает встроенную отладочную утилиту. Отладчик позволяет останавливать выполнение скрипта в произвольной точке. В этом случае вы увидите интерактивную подсказку. На этой подсказке вы можете выполнить любую команду fish (нет специальных команд отладки). Например, вы можете проверить или изменить значение любой переменной с помощью printf и set. В качестве другого примера, вы можете запустить status print-stack-trace, чтобы увидеть, как был достигнут этот разрыв. Для возобновления нормального выполнения скрипта просто введите exit или Control+D.

Чтобы начать сеанс отладки, просто выполните встроенную команду breakpoint в той точке функции или скрипта, где вы хотите получить управление. Кроме того, стандартное действие сигнала TRAP — вызов этой встроенной команды. Поэтому запущенный скрипт можно отладить, отправив ему сигнал TRAP с помощью команды kill. Попав в отладчик, легко вставить новые точки останова, используя функцию funced для изменения определения функции.

Дополнительная помощь и разработка

Если у вас есть вопрос, на который не отвечает эта документация, есть несколько способов получить помощь:

  • Страница GitHub
  • Официальный канал Gitter
  • Официальный список рассылки по адресу fish-users@lists.sourceforge.net
  • Канал IRC, #fish на irc.oftc.net

Если у вас есть улучшение для fish, вы можете отправить его через страницу GitHub.

Другие страницы справки

  • Введение
  • Команды
  • Архитектура
  • Учебник
  • Написание собственных дополнений
  • Часто задаваемые вопросы
  • Лицензия
  • Заметки о выпуске
  • Fish для пользователей bash

© 2020 fish-shell developers
Licensed under the GNU General Public License, version 2.
https://fishshell.com/docs/3.2/index

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API