Часто задаваемые вопросы
Какой аналог этой вещи из bash (или других оболочек)?
См. Fish для пользователей bash
Как установить или очистить переменную среды?
Используйте команду set:
set -x key value # typically set -gx key value set -e key
Начиная с fish 3.1, вы можете установить переменную среды только для одной команды, используя синтаксис key=value some command, как и в других оболочках. Две строки ниже ведут себя одинаково — в отличие от других оболочек, fish выведет value в обоих случаях:
key=value echo $key begin; set -lx key value; echo $key; end
Обратите внимание, что «exported» — это не область видимости, а дополнительный фрагмент состояния. Переменная может быть глобальной и экспортированной, локальной и экспортированной или даже универсальной и экспортированной. Обычно имеет смысл сделать экспортированную переменную глобальной.
Как проверить, определена ли переменная?
Используйте set -q var. Например, if set -q var; echo variable defined; end. Чтобы проверить несколько переменных, можно комбинировать с and и or следующим образом:
if set -q var1; or set -q var2
echo either variable defined
end
Помните, что определенная переменная также может быть пустой, либо не имея элементов (если установлена как set var) или содержа только пустые элементы (если установлена как set var ""). Читайте дальше, чтобы узнать, как с этим справиться.
Как проверить, что переменная не пуста?
Используйте string length -q -- $var. Например, if string length -q -- $var; echo not empty; end. Обратите внимание, что string length будет интерпретировать список нескольких переменных как дизъюнкцию (т. е. любое/или):
if string length -q -- $var1 $var2 $var3
echo at least one of these variables is not empty
end
В качестве альтернативы используйте test -n "$var", но помните, что переменная должна быть заключена в двойные кавычки. Например, if test -n "$var"; echo not empty; end. Команда test предоставляет свои собственные «и» (-a) и «или» (-o):
if test -n "$var1" -o -n "$var2" -o -n "$var3"
echo at least one of these variables is not empty
end
Если вы хотите узнать, содержит ли переменная никаких элементов, используйте set -q var[1].
Почему не работают set -Ux (экспортированные универсальные переменные)?
Уже существует глобальная переменная с тем же именем.
Переменные среды, такие как EDITOR или TZ, могут быть установлены глобально с помощью set -Ux Однако, если переменная среды уже установлена до запуска fish (например, скриптами входа или системными администраторами), она импортируется в fish как глобальная переменная. Области видимости переменных поиска с «внутрь наружу», что означает, что локальные переменные проверяются первыми, затем глобальные и, наконец, универсальные.
Это означает, что значение глобальной переменной имеет приоритет над универсальным значением.
Чтобы избежать этой проблемы, рассмотрите возможность изменения настройки, которую fish наследует. Если это невозможно, добавьте оператор в ваш файл настройки (обычно ~/.config/fish/config.fish):
set -gx EDITOR vim
Как запустить команду при каждом входе? Каким аналогом fish являются .bashrc или .profile?
Отредактируйте файл ~/.config/fish/config.fish 1, создав его, если он не существует (обратите внимание на ведущую точку).
В отличие от .bashrc и .profile, этот файл всегда читается, даже в неинтерактивных или логин-оболочках.
Чтобы сделать что-то только в интерактивных оболочках, проверьте status is-interactive так:
if status is-interactive
# use the coolbeans theme
fish_config theme choose coolbeans
end
-
1 -
Часть «~/.config» в этом случае может быть установлена с помощью $XDG_CONFIG_HOME, это просто значение по умолчанию.
Как установить свой приглашение?
Приглашение — это результат работы функции fish_prompt. Разместите его в ~/.config/fish/functions/fish_prompt.fish. Например, простое приглашение:
function fish_prompt
set_color $fish_color_cwd
echo -n (prompt_pwd)
set_color normal
echo -n ' > '
end
Также можно использовать инструмент веб-конфигурации fish_config, чтобы просмотреть и выбрать из галереи примеров приглашений.
Или можно использовать fish_config из командной строки:
> fish_config prompt show # displays all the prompts fish ships with > fish_config prompt choose disco # loads the disco prompt in the current shell > fish_config prompt save # makes the change permanent
Если нужно изменить существующее приглашение, можно использовать funced и funcsave так:
>_ funced fish_prompt # This opens up your editor (set in $EDITOR). # Modify the function, # save the file and repeat to your liking. # Once you are happy with it: >_ funcsave fish_prompt
Это также относится к fish_right_prompt и fish_mode_prompt.
Почему в приглашении отображается [I]?
Это fish_mode_prompt. Он отображается по умолчанию, когда активирован режим vi с помощью fish_vi_key_bindings.
Если вы не активировали режим vi специально, возможно, вы установили стороннюю тему или плагин, который это делает.
Если вы хотите изменить или отключить это отображение, измените функцию fish_mode_prompt, например, с помощью funced.
Как настроить цвета синтаксического выделения?
Используйте инструмент веб-конфигурации fish_config или измените переменные среды fish_color.
Также можно использовать fish_config в командной строке, например:
> fish_config theme show # to demonstrate all the colorschemes > fish_config theme choose coolbeans # to load the "coolbeans" theme > fish_config theme save # to make the change permanent
Как изменить сообщение приветствия?
Измените значение переменной fish_greeting или создайте функцию fish_greeting. Например, чтобы удалить приветствие:
set -U fish_greeting
Или, если вы предпочитаете не использовать универсальную переменную, используйте:
set -g fish_greeting
в файле config.fish.
Как запустить команду из истории?
Введите часть команды, а затем нажмите клавиши со стрелками ↑ (вверх) или ↓ (вниз), чтобы перейти к соответствующим совпадениям в истории. Дополнительные стандартные сочетания клавиш — Control+P (вверх) и Control+N (вниз). Подробнее см. Поисковая история команд.
Почему не работает замена по истории («!$» и т. д.)?
Потому что замена по истории — это неудобный интерфейс, который был изобретён до появления интерактивного редактирования строк. Вместо добавления этого псевдосинтаксиса fish выбирает удобные возможности поиска и воспроизведения истории. Переключение требует небольшого изменения привычек: если нужно изменить старую строку/слово, сначала воспроизведите её, затем отредактируйте.
В качестве особого случая, большая часть времени замена по истории используется как sudo !!. В этом случае просто нажмите Alt+S, и это восстановит вашу последнюю командную строку с префиксом sudo (или переключит префикс sudo на текущую командную строку, если там что-то есть).
В общем, воспроизведение истории в fish работает так:
- Как и в других оболочках, стрелка вверх ↑ воспроизводит целые строки, начиная с последней выполненной строки. Одно нажатие заменяет «!!», последующие нажатия заменяют «!-3» и т. д.
- Если нужная строка находится далеко в истории, введите любую часть строки, а затем несколько раз нажмите клавишу Вверх. Это отфильтрует воспроизводимые строки, содержащие этот текст, и вы быстрее дойдёте до нужной строки. Это заменяет «!vi», «!?bar.c» и т. д.
- Alt+↑ воспроизводит отдельные аргументы, начиная с последнего аргумента в последней выполненной строке. Одно нажатие заменяет «!$», последующие нажатия заменяют «!!:4» и т. д. Альтернативное сочетание клавиш — Alt+..
- Если нужный аргумент находится далеко в истории (например, на 2 строки назад — это много слов!), введите любую часть аргумента и нажмите Alt+↑. Это отобразит только аргументы, содержащие эту часть, и вы быстро получите то, что нужно. Попробуйте — это очень удобно!
- Если требуется повторное использование нескольких аргументов из одной строки («!!:3*» и т. п.), рассмотрите возможность воспроизведения всей строки и удаления ненужного (Alt+D и Alt+Backspace — ваши друзья).
См. документацию для получения более подробной информации об редактировании строк в fish.
Как запустить подкоманду? Обратные кавычки не работают!
fish использует круглые скобки для подкоманд. Например:
for i in (ls)
echo $i
end
Он также поддерживает знакомый синтаксис $() даже в кавычках. Обратные кавычки не поддерживаются, так как они не рекомендуются даже в оболочках POSIX. Они плохо вкладываются и трудно различимы от одинарных кавычек ('').
Моя команда (pkg-config) выдает вывод в виде одной длинной строки?
В отличие от других оболочек, fish разделяет подстановки команд только по символам новой строки, а не по пробелам, табуляции или символам в $IFS.
Это означает, что если вы выполните
count (printf '%s ' a b c)
будет выведено 1, потому что «a b c » используется как единое целое. Но если вы выполните
count (printf '%s\n' a b c)
будет выведено 3, потому что он передал count аргументы «a», «b» и «c» по отдельности.
В подавляющем большинстве случаев разделение по пробелам нежелательно, поэтому это улучшение. Именно поэтому вы слышите о проблемах с именами файлов со пробелами.
Однако иногда, особенно с pkg-config и связанными инструментами, требуется разделение по пробелам.
В этих случаях используйте string split -n " " следующим образом:
g++ example_01.cpp (pkg-config --cflags --libs gtk+-2.0 | string split -n " ")
-n так, чтобы удалялись пустые элементы, как это делают оболочки POSIX.
Как получить код завершения команды?
Используйте переменную $status. Она заменяет переменную $?, используемую в других оболочках.
somecommand
if test $status -eq 7
echo "That's my lucky number!"
end
Если вас интересует только успех или неудача, вы можете выполнить команду непосредственно как условие if:
if somecommand
echo "Command succeeded"
else
echo "Command failed"
end
Или если вы хотите выполнить одну команду в случае успеха или неудачи первой, используйте and или or.
somecommand or someothercommand
Дополнительную информацию см. в разделе Условные операторы и документации по test и if.
Моя команда выводит «No matches for wildcard», но работает в bash
Короче говоря: обрамление кавычками или экранирование символа подстановки:
scp user@ip:/dir/"string-*"
Когда fish видит необрамлённый *, он выполняет расширение символа подстановки. Это означает, что он пытается сопоставить имена файлов с заданной строкой.
Если символ подстановки не соответствует ни одному файлу, fish выводит ошибку вместо выполнения команды:
> echo *this*does*not*exist
fish: No matches for wildcard '*this*does*not*exist'. See `help expand`.
echo *this*does*not*exist 2>| xsel --clipboard
^
Теперь bash также пытается сопоставить файлы в этом случае, но когда не находит совпадения, он передаёт литеральную строку символа подстановки.
Это означает, что команды, подобные вышеприведённым
scp user@ip:/dir/string-*
или
apt install postgres-*
кажутся работающими, потому что в большинстве случаев строка не соответствует, и поэтому передаётся string-*, которая затем интерпретируется принимающей программой.
Но это также означает, что эти команды могут перестать работать в любой момент, как только будет найден соответствующий файл (поскольку он был создан или команда выполняется в другой рабочей директории), и для решения этой проблемы bash требует обходных путей, таких как
for f in ./*.mpg; do
# We need to test if the file really exists because
# the wildcard might have failed to match.
test -f "$f" || continue
mympgviewer "$f"
done
(из http://mywiki.wooledge.org/BashFAQ/004)
По этим причинам fish этого не делает и вместо этого ожидает, что звёздочки будут обрамлены кавычками или экранированы, если они не должны расширяться.
Это аналогично параметру «failglob» в bash.
Я случайно ввёл путь к директории, и fish сменил директорию. Что произошло?
Если fish не может найти команду с заданным именем, и она начинается с ., / или ~, fish проверит, существует ли директория с таким именем. Если она существует, fish предполагает, что вы хотите изменить свою директорию. Например, самый быстрый способ перейти в домашнюю директорию — просто нажать ~ и ввести.
Команда open не работает.
Команда open использует базу данных типов MIME и файлы .desktop, используемые Gnome и KDE для определения типов файлов и действий по умолчанию. Если хотя бы одна из этих сред установлена, но команда open не работает, это, вероятно, означает, что соответствующие файлы установлены в нестандартном месте. Рассмотрите возможность обратиться за дополнительной помощью.
Почему SSH/SCP/rsync не подключаются должным образом, когда fish — моя оболочка входа?
Эта проблема может проявляться как сообщения вида «Received message too long», «open terminal
failed: not a terminal», «Bad packet length» или «Connection refused» со странным выводом в сообщениях ssh_exchange_identification в журнале отладки.
Это обычно происходит, потому что fish всегда читает файл конфигурации пользователя файл конфигурации пользователя (~/.config/fish/config.fish), независимо от того, является ли оболочка интерактивной, оболочкой входа или нет.
Это упрощает вопросы, но также означает, что при генерации вывода config.fish это произойдёт даже в неинтерактивных оболочках, таких как та, в которой ssh/scp/rsync запускаются при подключении.
Любой вывод, генерируемый в config.fish, должен быть защищён status is-interactive (или status is-login, если вы предпочитаете):
if status is-interactive ... end
То же самое относится, например, к запуску tmux в config.fish без защитных мер, что вызовет сообщение sessions should be nested with care, unset $TMUX to force.
Я получаю странные графические артефакты (эффект лестницы, "призрачные" символы, курсор в неправильном положении…)?
В терминале приложение, работающее внутри него, и сам терминал должны согласовать ширину символов для обработки перемещения курсора.
Это важнее для fish, чем для других оболочек, потому что такие функции, как подсветка синтаксиса и автодополнение, реализованы перемещением курсора.
Иногда возникает несогласованность по ширине. Причин и решений для этого несколько:
- Возможно, символ слишком новый для вашей системы, и в этом случае следует воздержаться от его использования.
- Fish или ваш терминал могут не знать о символе или обработать его неправильно — в этом случае необходимо исправить fish или ваш терминал, или обновить до исправленной версии.
- Символ имеет «неопределённую» ширину, и fish считает, что она равна X, а ваш терминал считает, что равна Y. В этом случае необходимо либо изменить конфигурацию терминала, либо установить $fish_ambiguous_width на правильное значение.
- Символ — это эмодзи, а хост-система поддерживает только Unicode 8, в то время как вы используете терминал на системе, использующей Unicode >= 9. В этом случае установите $fish_emoji_width в 2.
Это также означает, что некоторые вещи не поддерживаются:
- Шрифты, не являющиеся моноширинными — fish никогда не сможет определить ширину конкретного символа, так как не влияет на отображение шрифта терминала.
- Разные ширины для нескольких символов с неопределённой шириной — fish не может знать, какую ширину вы назначили каждому символу.
Удаление fish
Если вы хотите удалить fish, сначала убедитесь, что fish не установлен как ваша оболочка. Запустите chsh -s /bin/bash , если вы не уверены.
Если вы установили его с помощью менеджера пакетов, просто используйте функцию удаления этого менеджера пакетов. Если вы построили fish самостоятельно, предполагая установку по пути /usr/local, выполните следующие действия:
rm -Rf /usr/local/etc/fish /usr/local/share/fish ~/.config/fish rm /usr/local/share/man/man1/fish*.1 cd /usr/local/bin rm -f fish fish_indent
Где найти дополнительные инструменты для fish?
Пользовательское сообщество fish расширяет fish уникальными и полезными способами с помощью скриптов, которые не всегда подходят для включения в пакет fish. Обычно это происходит потому, что они решают узкую проблему, вряд ли интересную широкой аудитории. Вы можете найти эти расширения, включая подсказки, темы и полезные функции, в различных репозиториях третьих сторон. К ним относятся:
Этот список не является исчерпывающим, и проект fish не имеет мнения о достоинствах перечисленных выше репозиториев или скриптов, найденных в них.
© 2022 fish-shell developers
Licensed under the GNU General Public License, version 2.
https://fishshell.com/docs/3.4/faq.html