Часто задаваемые вопросы
Какой эквивалент этой вещи из 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 предоставляет свои собственные 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, создав его, если он не существует (обратите внимание на ведущую точку).
-
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, чтобы просмотреть и выбрать из галереи образцов приглашений.
Если вы хотите изменить существующий приглашающий символ, вы можете использовать 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_greeting или создайте функцию fish_greeting. Например, чтобы удалить приветствие, используйте:
set -U fish_greeting
Или, если вы предпочитаете не использовать универсальную переменную, используйте:
set -g fish_greeting
в файле config.fish.
У меня появляется странный вывод перед каждым приглашением при использовании screen. В чем проблема?
Быстрый ответ:
Выполните следующую команду в fish:
function fish_title; end; funcsave fish_title
Проблема решена!
Длинный ответ:
Fish пытается установить сообщение в строке заголовка вашего терминала. Хотя сам screen поддерживает эту функцию, ваш терминал — нет. К сожалению, когда базовый терминал не поддерживает установку строки заголовка, screen просто пропускает коды escape и текст в базовый терминал вместо того, чтобы игнорировать их. Невозможно обнаружить и решить эту проблему изнутри fish, так как у fish нет способа узнать, какой тип базового терминала используется. Пока единственный способ исправить это — сбросить сообщение в строке заголовка, как предлагалось выше.
Обратите внимание, что у fish есть сообщение по умолчанию для строки заголовка, которое будет использоваться, если функция fish_title не определена. Поэтому простое удаление функции fish_title не сработает.
Как запустить команду из истории?
Наберите часть команды, а затем нажмите клавиши со стрелками вверх ↑ или вниз ↓ для навигации по совпадениям в истории. Дополнительные стандартные сочетания клавиш включают 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
Моя команда (pkg-config) выводит результат как одну длинную строку?
В отличие от других оболочек, fish разделяет подстановки команд только по символам новой строки, а не пробелам, табуляции или символам в $IFS.
Это означает, что если вы выполните
echo x(printf '%s ' a b c)x
Он выведет xa b c x, потому что «a b c » используется как один фрагмент. Но если вы выполните
echo x(printf '%s\n' a b c)x
он выведет xax xbx xcx.
В подавляющем большинстве случаев разделение по пробелам нежелательно, поэтому это улучшение.
Однако иногда, особенно с 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 проверит, существует ли директория с таким именем. Если существует, подразумевается, что вы хотите сменить рабочую директорию. Например, самый быстрый способ перейти в домашний каталог — просто нажать ~ и нажать Enter.
Как использовать - в качестве сокращения для cd -?
В версиях fish до 2.5.0 было возможно создать функцию с именем -, которая бы выполняла cd -. Изменения в версии 2.5.0 включали несколько исправлений ошибок, которые обеспечивают правило, что одиночный тире не является допустимым именем функции (или переменной). Однако вы можете добиться того же эффекта с помощью сокращения:
abbr -a -- - 'cd -'
Команда 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 в список оболочек, выполнив следующую команду (предполагается, что вы установили fish в /usr/local):
echo /usr/local/bin/fish | sudo tee -a /etc/shells
Если вы установили предварительно упакованную версию fish, менеджер пакетов должен был уже сделать это за вас.
Для изменения оболочки по умолчанию введите:
chsh -s /usr/local/bin/fish
Возможно, вам нужно изменить вышеуказанный путь на, например, /usr/bin/fish. Используйте команду which 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 не имеет мнения по поводу достоинств перечисленных выше репозиториев или скриптов, найденных в них.
© 2021 fish-shell developers
Licensed under the GNU General Public License, version 2.
https://fishshell.com/docs/3.3/faq.html