Использование UNIX
Ура, fish!
Дружественный Интерактивный Командный Интерпретатор (Friendly Interactive Shell, fish) прекрасно подходит как для новичков, так и для экспертов.
Серия контента:
Этот контент является частью # из серии # статей: Использование UNIX
Этот контент является частью серии:Использование UNIX
Следите за выходом новых статей этой серии.
Английский — это язык, способный привести в недоумение. Рассмотрим, например, слова moon и good. Для непосвященного слова должны рифмоваться, но первое из них произносится /mun/ (в соответствии с Международным фонетическим алфавитом), а второй /good/. Очевидно, что единственным правилом в английском языке является исключение.
Командные интерпретаторы UNIX так же сложны. Например, в командном интерпретаторе Борна – Bourne shell – (и в большинстве командных интерпретаторов UNIX) фразы '$var'
, "$var"
,
и `$var`
выглядят одинаково, но производят к совершенно разным результатам. (Каждый CLI, показанный в примерах в этой статье, предваряется названием действующего командного интерпретатора и номером команды.)
bash-1) # выявляем разницу между одинарными, двойными и обратными кавычками bash-2) var=ls bash-3) echo '$var' $var bash-4) echo "$var" ls bash-5) echo `$var` Rakefile app bin components config db doc lib log patches public script src test tmp vendor
В этой последовательности команд переменной var
присвоено строковое значение из двух символов ls. В начальной команде echo
апострофы предотвращают интерпретацию переменной, вместо этого выдавая точную копию текста, заключенного в апострофы, то есть строку, состоящую из четырех символов $var. Далее в команде 4 двойные кавычки выполняют интерпретацию переменной, так что результирующей строкой является ls. Наконец, обратные кавычки интерпретируют переменную, и выполняет промежуточный результат в новой копии интерпретатора. Таким образом,
`$var`
возвращает промежуточный результат — строку ls, которая выполняется как команда интерпретатора для получения содержимого локальной директории.
Конечно, все три оператора — одиночные, двойные и обратные кавычки — служат правильной цели, но, как и в случае исключений в английском языке, их запоминание и овладение вариантами может свести с ума. Вот еще доказательство: какая разница между
$var
и "$var"
? (Подсказка: предположим, что значение $var
содержит пробел.)
bash-1) # создайте три файла и попробуйте удалить два bash-2) touch three two one bash-3) var="one two" bash-4) rm "$var" rm: one two: No such file or directory bash-5) rm $var bash-6) ls three
Если переменная содержит пробел, двойные кавычки сохраняют расширение переменной целым, как один аргумент, иначе любой пробел в значении переменной интерпретируется как разделитель.
Да уж действительно! Синтаксис командного интерпретатора может сводить с ума. И это очень печально, так как в итоге интерфейс командной строки — одна из самых мощных возможностей UNIX — становится очень сложным для изучения. В действительности, противоречия, описанные выше, нервируют даже закаленных ветеранов.
К счастью, fish
(Friendly Interactive Shell, Дружественный Интерактивный Командный Интерпретатор) плывет, преодолевая мутное течение и обеспечивая стройный синтаксис и улучшенное восприятие для пользователя. Подобно другим командным интерпретаторам, fish
обеспечивает перенаправление, быстрые вызовы, универсализацию файловых имен (то есть, расширение шаблонов имен), вложенные командные интерпретаторы, дополнение по клавише Tab и переменные. Но, в отличие от других интерпретаторов
fish
кроме того поддерживает интерфейс командной строки с цветовой кодировкой, развитый редактор командной строки и хорошо документирован.
Кроме того, fish
разумно обеспечивает только один способ выполнения задачи. Если какая-то утилита UNIX выполняет отдельную задачу, то fish
не повторяет эту возможность как встроенную команду. Например, для завершения процессов
fish
использует системную утилиту /bin/kill. (Для сравнения, bourne shell реализует свою версию утилиты kill в виде встроенного приложения. Чтобы его использовать, нужно ввести /bin/kill
в командной строке bash.) Везде, где это возможно, fish
предпочитает простоту гибкости, делая использование более предсказуемым.
Давайте установим эту программу, закинем удочку и опробуем некоторые из многочисленных возможностей fish
.
Ловим рыбу
Fish
— это проект с открытым исходным кодом, созданный Акселем Лиленкранцем (Axel Liljencrantz), на который распространяется лицензия GNU General Public License, версии 2. На момент написания статьи самой свежей версией является fish
1.23.0, выпущенная 13 января 2008.
Если вы используете UNIX или UNIX-подобную систему, такую, как Linux® или Mac OS X, то в вашей системе
fish
должен собраться из исходного кода быстро и просто. Необходимые для этого шаги (см. Листинг 1:
- Скачайте самый свежий архив tar с исходным кодом программы.
- Распакуйте его.
- Перейдите в директорию с исходным кодом.
- Настройте сборку.
- Запустите
make
.
Сборка fish из исходных кодов
bash-1) wget http://www.fishshell.org/files/1.23.0/fish-1.23.0.tar.gz bash-2) tar xzvf fish-1.23.0.tar.gz bash-3) cd fish-1.23.0 bash-4) ./configure --without-xsel checking if autoconf needs to be run... no checking if autoheader needs to be run... no checking for /usr/pkg/include include directory... no ... bash-5) make gcc -c -o function.o function.c ... bash-6) sudo make install ... To use fish as your login shell: * add the line '/usr/bin/fish' to the file '/etc/shells'. * use the command 'chsh -s /usr/bin/fish'.
Если вы используете UNIX-подобную систему, то скрипт
configure
не требует обязательных дополнительных параметров. Тем не менее, чтобы сократить зависимости и разместить fish
в тех же директориях, что и обычные командные интерпретаторы, вы можете добавить опции
--without-xsel
и --prefix=/usr
, соответственно. (В Mac OS X версии 10.4 Leopard, также нужно добавить флаг
LDFLAGS=-liconv
. Если опустить эту опцию в Mac OS X, то служебные утилиты fish
не будут собраны из-за ошибки.)
Если вы используете популярный вариант UNIX, то скорей всего сможете найти уже собранные двоичные файлы, готовые к установке на ваш дистрибутив. Например, если вы используете Debian Linux, вы можете тотчас установить fish
по команде
sudo apt-get install fish
. Проверьте на домашней странице проекта доступность fish
для вашей системы.
Учимся на примерах
Перед погружением в более сложные темы, давайте взглянем, как обычные задачи командного интерпретатора решаются в fish
:
- Чтобы перенаправить стандартный ввод и стандартный вывод, используются операторы
<
и>
соответственно. Чтобы перенаправить стандартный вывод ошибок, используется символ карет (^
), как показано на рисунке 1. Чтобы дописать стандартный вывод ошибок к файлу, используется^^
.Рисунок 1 Перенаправление стандартного вывода ошибок оператором карет
Кликните, чтобы увидеть увеличенное изображение
В команде 3 сообщения об ошибках, выведенные командой
rm
, помещаются в файл с именем errors. Команда 4 отображает содержимое этого файла. Командный интерпретаторfish
имеет отличную поддержку перенаправления, например, для объединения дескрипторов в один поток и для закрытия дескрипторов.Кстати, цветной и подчеркнутый текст — это не типографская правка. Командный интерпретатор подсвечивает текст в интерфейсе командной строки по мере ввода. В строке зеленый цвет показывает, что имя команды введено правильно; неправильное имя команды окрашивается красным. Подчеркивание — это подсказка, говорящая, что заданный файл существует. (В следующем разделе ответные реакции оболочки описаны более подробно.)
- Чтобы запустить подоболочку (новый интерпретатор), используйте скобки (
()
), , как показано на рисунке 2. Текст, заключенный в скобки, интерпретируется как список команд и заменяется результатом их исполнения.Рисунок 2 Используйте скобки, чтобы запустить подоболочку
- Чтобы создать псевдоним или быстрый вызов, создайте функцию
fish
.Функция может содержать одну или более команд и специальную переменную
$argv
, автоматически расширяемую в список аргументов, переданных в изначальной командной строке.Список всех определенных функций можно вывести командой
functions
. Чтобы стереть функцию, используйтеfunctions --erase имя
, как вfunctions --erase ll
.Также возможно немедленно сохранить любую функцию, написанную в командной строке. Написав код, введите
funcsave имя
, какfuncsave ll
. Эта функция немедленно станет доступной для всех работающих в настоящий момент командных интерпретаторов и для тех, что будут запущены в будущем. Командаfunced имя
изменяет существующую функцию в интерактивном режиме. Командаfunced
обеспечивает полную подсветку синтаксиса, автодополнение по клавише Tab и автоматическую расстановку отступов;funcsave
иfunced
упрощают настройку командного интерпретатора. - Чтобы задать переменную, введите
set переменная имязначение
. Как и для встроенной переменнойfunctions
bвведитеset --erase переменная имя
, чтобы удалить значение переменной или удалить переменную. Чтобы получить значение переменной, введите знак ($
) и последующее имя переменной, как показано на рисунке 3.Рисунок 3 Проверка существования переменной
Кликните, чтобы увидеть увеличенное изображение
fish
предоставляет разумную опцию--query
для проверки того, определена ли переменная. Если да, тоset --query
возвращает код 0, показывающий что ошибок не произошло; иначе — возвращается 1. Оператор 6 объединяет две команды операторомor
: вторая команда (echo
) выполняется, только если первая завершится с ошибкой.
Так как же fish
обрабатывает все эти вселяющие ужас
$var
, '$var'
,
"$var"
и `$var`
? Как и ожидалось, работают следующие простые правила:
- Если значение переменной содержит пробел, то пробел всегда сохраняется и переменная всегда вычисляется в один аргумент (см.
рисунок 4.
Рисунок 4 Fish сохраняет целыми строки, содержащие пробел
- Если двойные кавычки являются наружными, то все переменные раскрываются.
- Если одиночные кавычки являются наружными, то переменные не раскрываются.
Давайте рассмотрим эти правила на практике.
Команда 1 создает четыре файла, где последний файл содержит пробел в имени. Команды 3 и 4 удаляют файл, имя которого содержится в переменной file
.
Команды 6 и 7 удаляют два файла, имена которых содержатся в переменной twofiles
Рассмотрим подробнее команду 6: поскольку значение не помещено в кавычки (ни одиночные, ни двойные), то пробел не защищен. Отсюда, команда 7 раскрывается на два аргумента и удаляет оба файла. Команды 9 и 10 повторяют сценарий команд 6 и 7.
Команды 11 и 12 демонстрируют правило пробела. Хотя в команде 12 переменная не заключена в двойные кавычки, fish
сохраняет пробел, установленный в команде 11. Очень хорошо.
Команды с 14 по 16 демонстрируют правила fish
, касающиеся вложенных кавычек. Снова взглянем на команды 11, 15 и 16. Командный интерпретатор использует цветовой код, чтобы показать спаренные кавычки и подкрепить правильный синтаксис. Взглянем также и на команды 9 и 11. Последняя команда подчеркнула имя файла, показывая, что файл существует. Отсутствие подчеркивания в команде 9 — это серьёзный намёк на то, что вы сделали что-то не так.
Дружественность— второе имя fish
.
Отличная функция для сухопутных крыс
Продолжаем разговор о дружественных функциях. Функция fish
завершение (дополнение) ввода табуляцией— это еще одно нововведение, которое и новички, и эксперты в UNIX найдут чрезвычайно полезным. Чтобы увидеть дополнение в действии, начинайте печатать, как показано в следующем примере. Нажимайте клавишу Tab в конце каждой строки.
Если вы не уверены в имени команды, то нажимайте клавишу Tab после того, как введете несколько символов, чтобы увидеть список возможных вариантов (см. рисунок 5). (Список в вашей системе может отличаться от списка, показанного здесь. Список зависит одновременно от значения переменной PATH и состава вашего UNIX.)
Рисунок 5 Нажмите Tab чтобы дополнить имя команды

Кликните, чтобы увидеть увеличенное изображение
Обратите внимание на красный текст в интерфейсе командной строки. Если fish
не распознает имя команды, то отображает его красным. Нажатие Tab показывает имена всех приложений (с кратким описанием), которые начинаются с последовательности букв, введенной вами. Также можно нажать Tab в пустой командной строке, чтобы увидеть все приложения, доступные из переменной PATH.
Если вы хотите знать, какие опции доступны для команды, то нажмите Tab после тире (-
) или двойного тире
(--
), как показано на рисунке 6.
Рисунок 6 Для дополнения опции также можно нажать Tab

Кликните, чтобы увидеть увеличенное изображение
Здесь fish
перечисляет доступные опции. Командный интерпретатор поддерживает обширный индекс стандартных команд и опций и, скорей всего, вы сможете получить нужную вам справку. Тем менее, специализированные или ещё более нестандартные утилиты могут не содержать нужных данных. Прочтите документацию fish
, чтобы узнать больше о написании собственных дополнений.
После ввода нескольких начальных букв опции также можно нажать Tab, что показано на рисунке 7. Командный интерпретатор покажет все возможные сочетания.
Рисунок 7 Также можно ввести только часть опции

Кликните, чтобы увидеть увеличенное изображение
Если вы не знаете, каким видом операндов оперирует команда,
fish
может помочь во многих случаях, но не во всех. Например, если ввести set
(или vared
,
редактор переменных fish
), пробел, и затем нажать Tab, то
fish
предоставит список доступных переменных. Аргумент является операндом для set
. Аналогично, если ввести пробел и нажать Tab, fish
отобразит список всех встроенных утилит и функций, которые расширяют список утилит, которые доступны вам в файловой системе.
В целом все встроенные утилиты и функции, включенные в fish
, имеют контекстно-зависимое завершение операндов. Попробуйте, например, команду cd
, как показано на рисунке 8.
Рисунок 8 Многие команды являются контекстно-зависимыми и представляют соответствующие аргументы

Кликните, чтобы увидеть увеличенное изображение
Функция cd
— это функция fish
, которая знает, что ее операнд — это существующая директория. Если после ввода cd
нажать Tab, то fish
покажет все существующие поддиректории, располагающиеся в каждой директории, указанной в переменной CDPATH.
Ещё одно «умное» дополнение связано с ssh
. Введите
ssh
с последующим пробелом, и затем нажмите Tab, чтобы увидеть список всех известных имен хостов, которые будут взяты из файла известных хостов вашего Secure Shell (обычно находящегося в ~/.ssh/known_hosts):
fish-1) ssh login.example.com (Hostname) host1.example.com (Hostname)
fish
также дополняет имена файлов и имена директорий. Опять же, по мере ввода имён, составляющих путь, выделяются правильные элементы.
Одно значительное отличие между fish
и другими командными интерпретаторами состоит в отсутствии коротких вызовов в истории команд, таких как !
,
!!
и !$
.
Ловись, рыбка!
Если вам нравится fish
и вы хотите использовать его в качестве исходной оболочки, добавьте путь к fish
в официальный список командных интерпретаторов, /etc/shells, и запустите команду chsh
:
bash-1) type fish fish is /usr/bin/fish bash-2) sudo vi /etc/shells bash-3) cat /etc/shells /bin/bash /bin/csh /bin/ksh /bin/sh /bin/tcsh /bin/zsh /usr/bin/fish bash-4) chsh -s /usr/bin/fish Changing shell for strike Password: ******** bash-5) login strike Password: ******** Last login: Wed Oct 8 15:02:21 on ttys000 Welcome to fish, the friendly interactive shell Type help for instructions on how to use fish fish-1) echo $SHELL /usr/bin/fish
Заключение
В fish
. есть множество функций, которые можно узнать и оценить. Осмелюсь ли я сказать, что «в fish
много C
»?
Можно настраивать цвета подсветки синтаксиса. Можно настроить опции запуска, отредактировав ~/.config/fish/config.fish. Можно сделать переменные общими для нескольких процессов командного интерпретатора, используя универсальные переменные и fishd
. Эта оболочка также имеет великолепную функцию поиска в истории, интерактивный редактор переменных и интерактивный редактор командной строки.
А самое замечательное — огромное количество документации, полностью доступной из самого
fish
. Если вам нужна помощь, то просто напечатайте
help
в любой командной строке.
Доктора правы: fish
очень полезен!
Ресурсы для скачивания
Похожие темы
- Оригинал статьи: Go fish! . (EN)
- Руководство по
fish
.(EN) - Архитектура оболочки
fish
.(EN) -
Дополнительные скриншоты с
fish
. (EN) - Узнайте больше об оболочках UNIX. (EN)
-
Загрузите исходный код
fish
.(EN)