Учебник
Почему fish?
Fish — это полностью оснащенная командная оболочка (как bash или zsh), которая умна и удобна в использовании. Fish поддерживает мощные функции, такие как подсветка синтаксиса, автодополнение и вставка по табу, которые работают без обучения и конфигурации.
Если вы хотите сделать свою командную строку более продуктивной, полезной и интересной, не изучая сложный синтаксис и параметры конфигурации, то 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
Этот учебник предполагает базовые знания о командных оболочках и Unix-командах, а также о наличии рабочей копии fish.
Если у вас есть глубокое понимание других оболочек и вы хотите узнать, чем fish отличается, найдите волшебную фразу unlike other shells, которая используется для выявления важных отличий.
Или, если вам нужен быстрый обзор различий с другими оболочками, такими как Bash, см. Fish для пользователей Bash.
Для полного подробного описания того, как использовать fish интерактивно, см. Интерактивное использование.
Для всестороннего описания языка сценариев fish см. Язык Fish.
Выполнение команд
Fish выполняет команды, как и другие оболочки: вы вводите команду, за которой следуют её аргументы. Разделителями являются пробелы:
> echo hello world hello world
Это выполняет команду echo с аргументами hello и world. В данном случае это то же самое, что и один аргумент hello world, но во многих случаях это не так. Если вам нужно передать аргумент, содержащий пробел, вы можете экранировать его с помощью обратного слэша или ограничить его с помощью одинарных или двойных кавычек:
> mkdir My\ Files # Makes a directory called "My Files", with a space in the name > cp ~/Some\ File 'My Files' # Copies a file called "Some File" in the home directory to "My Files" > ls "My Files" Some File
Получение справки
Запустите help чтобы открыть справку fish в веб-браузере, и man со страницей (например, fish-language) чтобы открыть её в справке man. Вы также можете запросить помощь по конкретной команде, например, help set чтобы открыть её в веб-браузере, или man set чтобы увидеть её в терминале.
> man set set - handle shell variables Synopsis...
Подсветка синтаксиса
Вы быстро заметите, что fish выполняет подсветку синтаксиса по мере ввода. Некорректные команды по умолчанию выделяются красным цветом:
> /bin/mkd
Команда может быть некорректной, потому что она не существует или ссылается на файл, который нельзя выполнить. Когда команда становится корректной, она отображается другим цветом:
> /bin/mkdir
Действительные пути к файлам подчёркиваются по мере ввода:
> cat ~/somefi
Это сообщает вам, что существует файл, начинающийся с somefi, что является полезной обратной связью во время ввода.
Эти цвета, и многие другие, можно изменить, запустив fish_config, или изменив переменные цвета напрямую.
Например, если вы хотите отключить (почти) всю подсветку:
fish_config theme choose none
Это выбирает тему «none». Чтобы увидеть все темы:
fish_config theme show
Просто запустив 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+→ (стрелка вправо). Если автодополнение не то, что вам нужно, просто проигнорируйте его.
Если вы не хотите автодополнения, вы можете отключить его, установив $fish_autosuggestion_enabled в 0:
set -g fish_autosuggestion_enabled 0
Автодополнение по табу
Набор функций автодополнения по табу работает «из коробки».
Нажмите 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 это создало бы две директории «Мистер» и «Лапша». В fish была создана только одна: переменная имела значение «Мистер Лапша», поэтому это был аргумент, переданный в 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 # Will print: # 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
Если вам нужна подстановка команд, вывод которой является одним аргументом без каких-либо разделений, используйте подстановку команд в кавычках:
> echo "first line second line" > myfile > set myfile "$(cat myfile)" > printf '|%s|' $myfile |first line second line|
Для получения дополнительной информации см. Подстановку команд.
Разделение команд (точка с запятой)
Как и другие оболочки, fish позволяет использовать несколько команд как на отдельных строках, так и на одной строке.
Чтобы написать их на одной строке, используйте точку с запятой (;). Это означает, что следующие два примера эквивалентны:
echo fish; echo chips # or echo fish echo chips
Код выхода
При завершении команда возвращает код состояния в виде целого числа без знака.
В отличие от других оболочек, fish сохраняет код выхода последней команды в $status вместо $?.
> false > echo $status 1
Это указывает на то, как команда справилась — 0 обычно означает успех, а остальные означают разного рода неудачи. Например, set --query fish возвращает количество переменных, которые он запросил, но которые не были установлены — set --query PATH обычно возвращает 0, set --query arglbargl boogagoogoo обычно возвращает 2.
Также существует переменная списка $pipestatus для кодов выхода 1 процессов в конвейере.
Для получения дополнительной информации см. Переменную состояния.
-
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
# prints: Hello
say_hello everybody!
# prints: Hello everybody!
В отличие от других оболочек, fish не имеет псевдонимов или специального синтаксиса приглашения. Их заменяют функции. 2
Вы можете перечислить имена всех функций с помощью встроенной команды functions (обратите внимание на множественное число!). fish поставляется с несколькими функциями:
> functions N_, abbr, alias, bg, cd, cdh, contains_seq, 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, open, popd, prevd, 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
# Prints:
# 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 для веб-интерфейса или 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, есть много подробной документации, официальный канал gitter, официальный список рассылки и страница github.
© 2022 fish-shell developers
Licensed under the GNU General Public License, version 2.
https://fishshell.com/docs/3.5/tutorial.html