Учебник по fish
Почему fish?
fish — это полностью оборудованная командная оболочка (как bash или zsh), которая умная и удобная для пользователя. fish поддерживает мощные функции, такие как подсветка синтаксиса, автодополнение и автоподстановка, которые работают без каких-либо настроек или обучения.
Если вы хотите сделать свою командную строку более продуктивной, полезной и интересной, не изучая при этом сложный синтаксис и множество опций настройки, то fish может быть именно тем, что вам нужно!
Изучение fish
Этот учебник предполагает базовое понимание командных оболочек и команд Unix, а также наличие рабочей копии fish.
Если вы хорошо знакомы с другими оболочками и хотите узнать, чем fish отличается, найдите магическую фразу unlike other shells, которая используется для указания важных отличий.
При запуске fish, вы должны увидеть следующее:
Welcome to fish, the friendly interactive shell Type help for instructions on how to use fish you@hostname ~>
fish поставляется с параметрами командной строки, показывающими ваше имя пользователя, имя хоста и текущую рабочую директорию. Вы узнаете как изменить свой параметр командной строки далее. В дальнейшем мы будем использовать «>», чтобы сэкономить место.
Выполнение команд
fish выполняет команды, как и другие оболочки: вы вводите команду, за которой следуют ее аргументы. Разделителями являются пробелы:
> echo hello world 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
fish будет подчёркивать допустимые пути к файлам по мере их ввода:
> 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 перенаправляется с помощью знака «^»
> grep fish < /etc/shells > ~/output.txt ^ ~/errors.txt
Автодополнение
fish предлагает команды по мере ввода, отображая предложение справа от курсора серым цветом. Например:
> /bin/hostname
Он знает пути и опции:
> grep --ignore-case
И историю тоже. Введите команду один раз, и вы можете восстановить ее, просто набрав несколько букв:
> r<\@args{ync} \ ssh . myname@somelonghost.com:/some/long/path/doo/dee/doo/dee/doo}
Чтобы принять автодополнение, нажмите → или Control-F. Чтобы принять отдельное слово из автодополнения, нажмите Alt-→ (стрелка вправо). Если автодополнение не подходит, просто игнорируйте его.
Автозаполнение по клавише Tab
fish поставляется с богатым набором автозаполнения, которые работают "из коробки".
Нажмите Tab, и fish попытается завершить команду, аргумент или путь:
> /pri @key{Tab} → /private/
Если существует несколько вариантов, он отобразит их:
> ~/stuff/s @key{Tab}
~/stuff/script.sh (Executable, 4.8kB) ~/stuff/sources/ (Directory)
Нажмите клавишу Tab еще раз, чтобы перейти к другим вариантам.
fish также может завершать многие команды, например, ветви git:
> git merge pr @key{Tab} → git merge prompt_designer
> git checkout b @key{Tab}
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 не имеет специального синтаксиса для установки переменных. Вместо этого он использует обычную команду: set, которая принимает имя переменной и ее значение.
> set name 'Mister Noodle' > echo $name Mister Noodle
(Обратите внимание на кавычки: без них Mister и Noodle были бы отдельными аргументами, а $name бы преобразовался в список из двух элементов.)
В отличие от других оболочек, переменные не разделяются после подстановки:
> mkdir $name > ls Mister Noodle
В bash это привело бы к созданию двух каталогов «Mister» и «Noodle». В fish, был создан только один: значение переменной было «Mister Noodle», поэтому это тот аргумент, который был передан mkdir, включая пробелы. Другие оболочки используют термин «массивы» вместо списков.
Код завершения
В отличие от других оболочек, fish хранит код завершения последней команды в $status вместо $?.
> false > echo $status 1
Ноль считается успехом, а ненулевое значение — ошибкой.
Экспорт (переменные оболочки)
В отличие от других оболочек, fish не имеет команды export. Вместо этого переменная экспортируется с помощью опции к set, либо --export, либо просто -x.
> set -x MyVariable SomeValue > env | grep MyVariable MyVariablem=SomeValue
Вы можете удалить переменную с помощью -e или --erase
> set -e MyVariable > env | grep MyVariable (no output)
Списки
Команда set выше использовала кавычки, чтобы убедиться, что Mister Noodle был одним аргументом. Если бы это было два аргумента, то name был бы списком длиной 2. На самом деле, все переменные в fish фактически являются списками, которые могут содержать любое количество значений или вообще не содержать их.
Некоторые переменные, например, $PWD, содержат только одно значение. По соглашению мы говорим о значении этой переменной, но фактически имеем в виду её первое (и единственное) значение.
Другие переменные, например, $PATH, действительно содержат несколько значений. Во время расширения переменных переменная расширяется, чтобы стать несколькими аргументами:
> echo $PATH /usr/bin /bin /usr/sbin /sbin /usr/local/bin
Обратите внимание, что три переменные среды автоматически разделены двоеточием, чтобы стать списками, когда запускается fish: PATH, CDPATH, MANPATH. Наоборот, они объединяются двоеточием при экспорте в дочерние команды. Все остальные переменные среды (например, LD_LIBRARY_PATH) с аналогичной семантикой рассматриваются как простые строки.
Списки не могут содержать другие списки: рекурсии нет. Переменная — это список строк, и всё.
Получить длину списка можно с помощью 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 -l a 1 2 3 > set -l 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 " ") -lgio-2.0 -lgobject-2.0 -lglib-2.0
Разделение команд (точка с запятой)
Как и в других оболочках, fish позволяет использовать несколько команд, как на отдельных строках, так и на одной строке.
Чтобы написать их в одной строке, используйте точку с запятой (;). Это означает, что следующие два примера эквивалентны:
echo fish; echo chips # or echo fish echo chips
Комбинирующие команды (И, Или, Не)
В отличие от других оболочек, fish не имеет специального синтаксиса, такого как && или || для объединения команд. Вместо этого он имеет команды and, or, и not.
> cp file1.txt file1_bak.txt; and echo "Backup successful"; or echo "Backup failed" Backup failed
Как упоминалось в разделе о точке с запятой, это также можно записать на нескольких строках, как показано ниже:
cp file1.txt file1_bak.txt and echo "Backup successful" or echo "Backup failed"
Условные операторы (Если, Иначе, Переключатель)
Используйте if, else if, и else для условного выполнения кода на основе кода завершения команды.
if grep fish /etc/shells
echo Found fish
else if grep bash /etc/shells
echo Found bash
else
echo Got nothing
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 не имеет псевдонимов или специального синтаксиса приглашения. Их заменяют функции.
Вы можете перечислить имена всех функций с помощью ключевого слова functions (обратите внимание на множественное число!). fish изначально содержит ряд функций:
> functions alias, cd, delete-or-exit, dirh, dirs, down-or-search, eval, export, fish_command_not_found_setup, fish_config, fish_default_key_bindings, fish_prompt, fish_right_prompt, fish_sigtrap_handler, fish_update_completions, funced, funcsave, grep, help, history, isatty, ls, man, math, nextd, nextd-or-forward-word, open, popd, prevd, prevd-or-backward-word, prompt_pwd, psub, pushd, seq, setenv, trap, type, umask, up-or-search, vared
Вы можете просмотреть исходный код любой функции, передав её имя в команду functions:
> functions ls
function ls --description 'List contents of directory'
command ls -G $argv
end
Циклы
Циклы while:
> while true
echo "Loop forever"
end
Loop forever
Loop forever
Loop forever
...
Циклы 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, и её вывод используется в качестве приглашения.
Вы можете определить собственное приглашение:
> function fish_prompt
echo "New Prompt % "
end
New Prompt %
Несколько строк допустимы. Цвета могут быть заданы с помощью set_color, передавая ему именованные ANSI-цвета или значения RGB в шестнадцатеричном формате:
> function fish_prompt
set_color purple
date "+%m/%d/%y"
set_color FF0
echo (pwd) '>'
set_color normal
end
02/06/13
/home/tutorial >
Вы можете выбрать некоторые образцы приглашений, выполнив fish_config prompt. fish также поддерживает RPROMPT через fish_right_prompt.
$PATH
$PATH — это переменная среды, содержащая каталоги, в которых fish ищет команды. В отличие от других оболочек, $PATH является списком, а не строкой, разделённой двоеточием.
Чтобы добавить /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)
Вы можете сделать это непосредственно в config.fish, как вы могли бы сделать в других оболочках с помощью .profile. См. этот пример.
Более быстрый способ — изменить переменную $fish_user_paths универсальную переменную, которая автоматически добавляется в начало $PATH. Например, чтобы постоянно добавить /usr/local/bin в $PATH, можно написать:
> set -U fish_user_paths /usr/local/bin $fish_user_paths
Преимущество состоит в том, что вам не нужно возиться с файлами: достаточно один раз выполнить эту команду в командной строке, и она повлияет на текущую сессию и все будущие инстансы. (Примечание: не следует добавлять эту строку в config.fish. В противном случае переменная будет становиться длиннее каждый раз при запуске 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 сталкивается с командой, он пытается загрузить функцию для этой команды, поискав файл с именем этой команды в ~/.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, как сейчас, так и в будущем — даже после перезагрузки. Вы можете сделать переменную универсальной с помощью set -U:
> set -U EDITOR vim
Теперь в другой оболочке:
> echo $EDITOR vim
Хотите узнать больше?
Если вы хотите узнать больше о fish, есть обширная подробная документация, официальный список рассылки, IRC-канал #fish на irc.oftc.net, и страница на github.
© 2005–2009 Axel Liljencrantz
Licensed under the GNU General Public License, version 2.
https://fishshell.com/docs/2.7/tutorial.html