Spec-Zone.ru › Fish 3.2

Учебник

Почему рыбка?

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

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

Начало работы

После установки просто введите fish в вашей текущей оболочке, чтобы попробовать её!

Вы увидите стандартный приглашающий символ fish, что означает, что всё настроено, и вы можете начать использовать fish:

> fish
Welcome to fish, the friendly interactive shell
Type help for instructions on how to use fish
you@hostname ~>

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

Отныне мы будем считать ваше приглашение просто > для экономии места.

Изучение fish

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

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

Выполнение команд

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

> echo hello world
hello world

Это выполняет команду echo с аргументами hello и world.

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

> mkdir My\ Files
> cp ~/Some\ File 'My Files'
> ls "My Files"
Some File

Команды могут быть объединены с помощью точек с запятой.

Получение справки

В fish отличная система справки и man-страницы. Запустите help для открытия справки в веб-браузере и man для открытия её в man-странице. Вы также можете запросить справку по конкретной команде, например, help set для открытия в веб-браузере или man set для просмотра в терминале.

> man set
set - handle shell variables
  Synopsis...

Подсветка синтаксиса

Вы быстро заметите, что fish выполняет подсветку синтаксиса по мере ввода. Неверные команды по умолчанию окрашиваются в красный цвет:

> /bin/mkd

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

> /bin/mkdir

Действительные пути к файлам подчёркиваются при вводе:

> cat ~/somefi

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

Эти и многие другие цвета можно изменить, запустив fish_config, или изменив переменные цвета напрямую.

Подстановочные знаки

Fish поддерживает знакомые подстановочные знаки *. Для перечисления всех файлов JPEG:

> ls *.jpg
lena.jpg
meena.jpg
santa maria.jpg

Вы можете включить несколько подстановочных знаков:

> ls l*.p*
lena.png
lesson.pdf

Особенно мощным является рекурсивный подстановочный знак **, который выполняет поиск по директориям рекурсивно:

> ls /var/**.log
/var/log/system.log
/var/run/sntp.log

Если такая обходка директорий занимает много времени, вы можете нажать Control+C, чтобы прервать её.

Своды и перенаправления

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

> echo hello world | wc
      1       2      12

stdin и stdout можно перенаправить с помощью знакомых < и >. stderr перенаправляется с помощью 2>.

> grep fish < /etc/shells > ~/output.txt 2> ~/errors.txt

Чтобы перенаправить stdout и stderr в один файл, вам необходимо сначала перенаправить stdout, а затем stderr в stdout:

> make > make_output.txt 2>&1

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

По мере ввода fish будет предлагать команды справа от курсора серым цветом. Например:

> /bin/hostname

Он знает о путях и опциях:

> grep --ignore-case

И о истории тоже. Введите команду один раз, и вы можете её вызвать, просто набрав несколько букв:

> rsync -avze ssh . myname@somelonghost.com:/some/long/path/doo/dee/doo/dee/doo

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

Вставка по нажатию клавиши Tab

Набор функций автодополнения по нажатию клавиши Tab работает «из коробки».

Нажмите Tab, и fish попытается дополнить команду, аргумент или путь:

> /priTab => /private/

Если существует более одного варианта, он отобразит их:

> ~/stuff/sTab
~/stuff/script.sh  (Executable, 4.8kB)  ~/stuff/sources/  (Directory)

Нажмите Tab ещё раз, чтобы перейти к вариантам.

fish также может дополнить многие команды, такие как ветки git:

> git merge prTab => git merge prompt_designer
> git checkout bTab
builtin_list_io_merge (Branch) builtin_set_color (Branch) busted_events (Tag)

Попробуйте нажать Tab и посмотреть, что может сделать fish!

Переменные

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

> echo My home directory is $HOME
My home directory is /home/tutorial

Подстановка переменных также происходит в двойных кавычках, но не в одинарных:

> echo "My current directory is $PWD"
My current directory is /home/tutorial
> echo 'My current directory is $PWD'
My current directory is $PWD

В отличие от других оболочек, в fish нет специального синтаксиса VARIABLE=VALUE для задания переменных. Вместо этого есть обычная команда: set, которая принимает имя переменной и её значение.

> set name 'Mister Noodle'
> echo $name
Mister Noodle

(Обратите внимание на кавычки: без них Mister и Noodle были бы отдельными аргументами, а $name превратилось бы в список из двух элементов.)

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

> mkdir $name
> ls
Mister Noodle

В bash это создало бы две директории «Mister» и «Noodle». В fish создалась только одна: переменная имела значение «Mister Noodle», поэтому именно этот аргумент был передан в mkdir, со всеми пробелами. Другие оболочки используют термин «массивы» вместо списков.

Вы можете удалить (или «удалить») переменную с помощью -e или --erase

> set -e MyVariable
> env | grep MyVariable
(no output)

Экспорт (переменные оболочки)

Иногда вам нужно, чтобы переменная была доступна внешней команде, часто в качестве настройки. Например, многие программы, такие как git или man считывают переменную $PAGER, чтобы определить ваш предпочтительный просмотрщик (программа, которая позволяет прокручивать текст). Другие используемые переменные включают $BROWSER, $LANG (для настройки языка) и $PATH. Вы заметите, что они написаны с использованием ПРОПИСНЫХ букв, но это всего лишь соглашение.

Чтобы передать переменную внешней команде, её нужно «экспортировать». В отличие от других оболочек, в fish нет команды export. Вместо этого переменная экспортируется с помощью опции к команде set, либо --export или просто -x.

> set -x MyVariable SomeValue
> env | grep MyVariable
MyVariable=SomeValue

Она также может быть убрана из экспорта с помощью --unexport или -u.

Это работает и наоборот! Если fish запускается чем-то ещё, она наследует экспортированные переменные родителя. Таким образом, если ваш эмулятор терминала запускает fish, и она экспортирует $LANG со значением en_US.UTF-8, fish получит эту настройку. И то, что запустило ваш эмулятор терминала, также передало ему некоторые переменные, которые оно передаст, если не решит их не передавать. Так fish обычно получает значения для таких вещей, как $LANG, $PATH и $TERM, без необходимости их повторного указания.

Обратите внимание, что экспортированные переменные могут быть локальными, глобальными или универсальными — «экспортированный» не относится к области видимости. Обычно вы сделаете их глобальными с помощью set -gx MyVariable SomeValue.

Списки

Команда set выше использовала кавычки, чтобы гарантировать, что Mister Noodle был одним аргументом. Если бы это были два аргумента, тогда name был бы списком длиной 2. На самом деле, все переменные в fish на самом деле являются списками, которые могут содержать любое количество значений или не содержать их вообще.

У некоторых переменных, например, $PWD, есть только одно значение. По соглашению, мы говорим о значении этой переменной, но на самом деле имеем в виду её первое (и единственное) значение.

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

> echo $PATH
/usr/bin /bin /usr/sbin /sbin /usr/local/bin

Переменные, имена которых оканчиваются на «PATH», автоматически разделяются на двоеточиях, чтобы стать списками. Они объединяются с помощью двоеточий при экспорте в подкоманды. Это необходимо для совместимости с другими инструментами, которые ожидают, что $PATH будет использовать двоеточия. Вы также можете явно добавить эту особенность к переменной с помощью set --path, или удалить её с помощью set --unpath.

Списки не могут содержать другие списки: рекурсии нет. Переменная — это список строк, точка.

Получить длину списка можно с помощью count:

> count $PATH
5

Вы можете добавить (или добавить в начало) в список, установив список равным себе с дополнительными аргументами. Здесь мы добавляем /usr/local/bin в $PATH:

> set PATH $PATH /usr/local/bin

Вы можете получить доступ к отдельным элементам с помощью квадратных скобок. Нумерация начинается с 1 с начала и -1 с конца:

> echo $PATH
/usr/bin /bin /usr/sbin /sbin /usr/local/bin
> echo $PATH[1]
/usr/bin
> echo $PATH[-1]
/usr/local/bin

Вы также можете получить доступ к диапазонам элементов, известным как «слайсы»:

> echo $PATH[1..2]
/usr/bin /bin
> echo $PATH[-1..2]
/usr/local/bin /sbin /usr/sbin /bin

Вы можете перебирать список (или слайс) с помощью цикла for:

> for val in $PATH
    echo "entry: $val"
  end
entry: /usr/bin/
entry: /bin
entry: /usr/sbin
entry: /sbin
entry: /usr/local/bin

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

> set a 1 2 3
> set 1 a b c
> echo $a$1
1a 2a 3a 1b 2b 3b 1c 2c 3c
> echo $a" banana"
1 banana 2 banana 3 banana
> echo "$a banana"
1 2 3 banana

Это похоже на расширение фигурных скобок.

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

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

> echo In (pwd), running (uname)
In /home/tutorial, running FreeBSD

Распространённый приём — захватить вывод команды в переменную:

> set os (uname)
> echo $os
Linux

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

> touch "testing_"(date +%s)".txt"
> ls *.txt
testing_1360099791.txt

В отличие от других оболочек, fish не разделяет подстановки команд по пробелам (например, пробелам или табуляторам), а только по новым строкам. Это может быть проблемой с командами, такими как pkg-config , которые печатают то, что должно быть несколькими аргументами в одной строке. Чтобы разделить их и по пробелам, используйте string split.

> printf '%s\n' (pkg-config --libs gio-2.0)
-lgio-2.0 -lgobject-2.0 -lglib-2.0
> printf '%s\n' (pkg-config --libs gio-2.0 | string split -n " ")
-lgio-2.0
-lgobject-2.0
-lglib-2.0

Разделение команд (точка с запятой)

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

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

echo fish; echo chips

# or
echo fish
echo chips

Код завершения

При завершении команда возвращает код состояния в виде неотрицательного целого числа.

В отличие от других оболочек, fish сохраняет код завершения последней команды в $status вместо $?.

> false
> echo $status
1

Это указывает на то, как прошла команда — 0 обычно означает успех, в то время как другие значения указывают на различные виды ошибок. Например, set --query возвращает количество не заданных переменных, которые она запросила — set --query PATH обычно возвращает 0, set --query arglbargl boogagoogoo обычно возвращает 2.

Также существует переменная $pipestatus для хранения кодов завершения процессов в конвейере.

[1] или "статусы", если хотите, или "статусы" если вы путешествовали во времени из Древнего Рима или работаете учителем латинского языка

Комбинирующие операторы (И, Или, Не)

fish поддерживает хорошо знакомые && и || для объединения команд и ! для их отрицания:

> ./configure && make && sudo make install

Здесь, make выполняется только в том случае, если ./configure завершится успешно (вернёт 0), и sudo make install выполняется только в том случае, если ./configure и make завершаются успешно.

fish также поддерживает and, or и not. Первые два являются модификаторами задач и имеют более низкий приоритет. Пример использования:

> cp file1 file1_bak && cp file2 file2_bak; and echo "Backup successful"; or echo "Backup failed"
Backup failed

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

cp file1 file1_bak && cp file2 file2_bak
and echo "Backup successful"
or echo "Backup failed"

Условные операторы (Если, Иначе, Переключатель)

Используйте if и else для условного выполнения кода на основе кода завершения команды.

if grep fish /etc/shells
    echo Found fish
else if grep bash /etc/shells
    echo Found bash
else
    echo Got nothing
end

Для сравнения строк или чисел или проверки свойств файлов (существует ли файл, разрешен ли доступ на запись и т. д.), используйте test, например

if test "$fish" = "flounder"
    echo FLOUNDER
end

# or

if test "$number" -gt 5
    echo $number is greater than five
else
    echo $number is five or less
end

# or

# This test is true if the path /etc/hosts exists
# - it could be a file or directory or symlink (or possibly something else).
if test -e /etc/hosts
    echo We most likely have a hosts file
else
    echo We do not have a hosts file
end

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

if grep fish /etc/shells; and command -sq fish
    echo fish is installed and configured
end

Для ещё более сложных условий используйте begin и end для группировки частей условий.

Также существует команда switch:

switch (uname)
case Linux
    echo Hi Tux!
case Darwin
    echo Hi Hexley!
case FreeBSD NetBSD DragonFly
    echo Hi Beastie!
case '*'
    echo Hi, stranger!
end

Обратите внимание, что case не выполняет сквозного перехода и может принимать несколько аргументов или (скобочные) подстановочные знаки.

Функции

Функция fish — это список команд, которые могут необязательно принимать аргументы. В отличие от других оболочек, аргументы не передаются в «переменные с номерами», например $1, а вместо этого в одном списке $argv. Для создания функции используйте встроенную команду function:

> function say_hello
     echo Hello $argv
  end
> say_hello
Hello
> say_hello everybody!
Hello everybody!

В отличие от других оболочек, fish не имеет псевдонимов или специального синтаксиса приглашения. Функции выполняют эту задачу. [2]

Вы можете вывести имена всех функций с помощью встроенной команды functions (обратите внимание на множественное число!). fish изначально содержит ряд функций:

> functions
N_, abbr, alias, bg, cd, cdh, contains_seq, delete-or-exit, dirh, dirs, disown, down-or-search, edit_command_buffer, export, fg, fish_add_path, fish_breakpoint_prompt, fish_clipboard_copy, fish_clipboard_paste, fish_config, fish_default_key_bindings, fish_default_mode_prompt, fish_git_prompt, fish_hg_prompt, fish_hybrid_key_bindings, fish_indent, fish_is_root_user, fish_job_summary, fish_key_reader, fish_md5, fish_mode_prompt, fish_npm_helper, fish_opt, fish_print_git_action, fish_print_hg_root, fish_prompt, fish_sigtrap_handler, fish_svn_prompt, fish_title, fish_update_completions, fish_vcs_prompt, fish_vi_cursor, fish_vi_key_bindings, funced, funcsave, grep, help, history, hostname, isatty, kill, la, ll, ls, man, nextd, nextd-or-forward-word, open, popd, prevd, prevd-or-backward-word, prompt_hostname, prompt_pwd, psub, pushd, realpath, seq, setenv, suspend, trap, type, umask, up-or-search, vared, wait

Вы можете просмотреть исходный код любой функции, передав её имя в functions:

> functions ls
function ls --description 'List contents of directory'
    command ls -G $argv
end
[2] Существует функция под названием alias, но она всего лишь сокращение для создания функций.

Циклы

Циклы while:

> while true
    echo "Loop forever"
end
Loop forever
Loop forever
Loop forever
... # yes, this really will loop forever. Unless you abort it with ctrl-c.

Циклы for могут использоваться для итерирования по списку. Например, по списку файлов:

> for file in *.txt
    cp $file $file.bak
end

Итерирование по списку чисел можно выполнить с помощью seq:

> for x in (seq 5)
    touch file_$x.txt
end

Приглашение

В отличие от других оболочек, нет переменной приглашения, такой как PS1. Для отображения приглашения fish выполняет функцию fish_prompt, а её вывод используется в качестве приглашения. И если она существует, fish также выполняет функцию fish_right_prompt, а её вывод используется в качестве правого приглашения.

Вы можете определить собственное приглашение из командной строки:

> function fish_prompt; echo "New Prompt % "; end
New Prompt % _

Затем, если вы удовлетворены им, вы можете сохранить его на диск, набрав funcsave fish_prompt. Это сохранит приглашение в ~/.config/fish/functions/fish_prompt.fish. (Или, если хотите, вы можете создать этот файл вручную с самого начала.)

Несколько строк допустимы. Цвета можно задать с помощью set_color, передав ей имена ANSI-цветов или значения RGB в шестнадцатеричном формате:

function fish_prompt
    set_color purple
    date "+%m/%d/%y"
    set_color F00
    echo (pwd) '>' (set_color normal)
end

Это приглашение будет выглядеть так:

02/06/13
/home/tutorial > _

Вы можете выбрать среди некоторых образцов приглашений, выполнив fish_config prompt.

$PATH

$PATH — это переменная среды, содержащая каталоги, в которых fish ищет команды. В отличие от других оболочек, $PATH является списком, а не строкой, разделённой двоеточиями.

Fish позаботится о том, чтобы установить $PATH по умолчанию, но обычно она просто наследуется от родительского процесса fish и устанавливается в значение, имеющее смысл для системы — см. Экспорт.

Чтобы добавить /usr/local/bin и /usr/sbin в $PATH, вы можете написать:

> set PATH /usr/local/bin /usr/sbin $PATH

Чтобы удалить /usr/local/bin из $PATH, вы можете написать:

> set PATH (string match -v /usr/local/bin $PATH)

Для совместимости с другими оболочками и внешними командами $PATH является переменной пути, и поэтому будет объединена двоеточиями (а не пробелами), когда вы её заключите в кавычки:

> echo "$PATH"
/usr/local/sbin:/usr/local/bin:/usr/bin

и она будет экспортирована таким образом, и при запуске fish она разделит полученный $PATH на список по двоеточиям.

Вы можете сделать это непосредственно в config.fish, как вы могли бы сделать это в других оболочках с помощью .profile. См. этот пример.

Более быстрый способ — использовать функцию fish_add_path, которая добавляет указанные каталоги в путь, если они ещё не включены. Она делает это, изменяя $fish_user_paths универсальную переменную, которая автоматически добавляется к $PATH. Например, чтобы постоянно добавить /usr/local/bin в ваш $PATH, вы можете написать:

> fish_add_path /usr/local/bin

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

Или вы можете изменить $fish_user_paths самостоятельно, но будьте осторожны, чтобы не добавлять к нему безусловно в config.fish, иначе он будет становиться всё длиннее и длиннее.

Загрузка (Где .bashrc?)

Fish начинает с выполнения команд в ~/.config/fish/config.fish. Вы можете создать его, если он не существует.

Можно напрямую создавать функции и переменные в файле config.fish с помощью команд, показанных выше. Например:

> cat ~/.config/fish/config.fish

set -x PATH $PATH /sbin/

function ll
    ls -lh $argv
end

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

Если вы хотите организовать свою конфигурацию, fish также читает команды из файлов .fish в ~/.config/fish/conf.d/. Подробности см. в инициализации.

Автозагрузка функций

Когда fish встречает команду, она пытается загрузить функцию для этой команды, выполняя поиск файла с именем этой команды в ~/.config/fish/functions/.

Например, если вы хотели иметь функцию ll, вы бы добавили текстовый файл ll.fish в ~/.config/fish/functions:

> cat ~/.config/fish/functions/ll.fish
function ll
    ls -lh $argv
end

Это предпочтительный способ определения приглашения:

> cat ~/.config/fish/functions/fish_prompt.fish
function fish_prompt
    echo (pwd) "> "
end

См. документацию по funced и funcsave для способов автоматического создания этих файлов, и $fish_function_path для управления их расположением.

Универсальные переменные

Универсальная переменная — это переменная, значение которой делится между всеми экземплярами fish, как текущими, так и будущими — даже после перезагрузки. Вы можете сделать переменную универсальной с помощью set -U:

> set -U EDITOR vim

Теперь в другой оболочке:

> echo $EDITOR
vim

Переход на fish?

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

Добавьте оболочку в /etc/shells с помощью:

> echo /usr/local/bin/fish | sudo tee -a /etc/shells

Измените оболочку по умолчанию с помощью:

> chsh -s /usr/local/bin/fish

Это предполагает, что вы установили fish в /usr/local/bin, что является стандартным расположением, когда вы компилируете его самостоятельно. Если вы установили его с помощью менеджера пакетов, обычное расположение — /usr/bin/fish, но менеджеры пакетов обычно уже добавляют его в /etc/shells. Просто замените правильное расположение.

(Чтобы изменить его обратно на другую оболочку, просто замените /usr/local/bin/fish на /bin/bash, /bin/tcsh или /bin/zsh соответственно в шагах выше.)

Готовы к большему?

Если вы хотите узнать больше о fish, есть много подробной документации, официальный канал gitter, официальный список рассылки и страница github.

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

Spec-Zone.ru

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