Часто задаваемые вопросы
Что эквивалентно этому элементу из 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
Обратите внимание, что «экспортировано» — это не область видимости, а дополнительный фрагмент состояния. Переменная может быть глобальной и экспортированной, локальной и экспортированной или даже универсальной и экспортированной. Обычно имеет смысл сделать экспортированную переменную глобальной.
Как проверить, определена ли переменная?
Используйте 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 предоставляет свои собственные and (-a) и or (-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
Как настроить свой приглашающий символ?
Приглашающий символ — это результат работы функции 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+R, чтобы открыть историю в просматриваемой странице с возможностью поиска. В этом просмотрщике вы можете нажать Control+R или Control+S для перемещения к более старой или более новой истории соответственно.
Дополнительные клавиши по умолчанию включают 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 для получения дополнительной информации.
Моя команда выводит «Нет совпадений для шаблона», но работает в 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
^
Теперь 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 проверит, существует ли каталог с таким именем. Если да, он предположит, что вы хотите изменить свой каталог. Например, самый быстрый способ перейти в домашний каталог — просто нажать ~ и нажать Enter.
Команда 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 не имеет мнения по поводу достоинств перечисленных выше репозиториев или скриптов, содержащихся в них.
© 2005-2009 Axel Liljencrantz, 2009-2023 fish-shell contributors
Licensed under the GNU General Public License, version 2.
https://fishshell.com/docs/3.7/faq.html