Spec-Zone.ru › Fish 3.3

Рыба для пользователей bash

Это краткое руководство для тех, кто знаком с bash (или, в меньшей степени, другими оболочками, такими как zsh или ksh) и хочет понять, чем отличается рыба. Рыба намеренно несовместима с POSIX, и некоторые вещи, к которым вы привыкли, работают иначе.

Многие вещи похожи — обе оболочки в основном расширяют командные строки для выполнения команд, имеют конвейеры, перенаправления, переменные, шаблоны, используют вывод команд различными способами. Этот документ быстро покажет вам различия.

Замены команд

В рыбе замены команд обозначаются как (command) вместо $(command) (или `command`).

Кроме того, она разделяет их только по символам новой строки вместо $IFS. Если вы хотите разделить по чему-то другому, используйте разделение строк, разделение строк0 или сбор строк. Если эти команды используются в качестве последней команды в замене команды, созданные разделения переносятся. Например:

for i in (find . -print0 | string split0)

правильно обработает все возможные имена файлов.

Переменные

Рыба устанавливает и удаляет переменные с помощью команды set вместо VAR=VAL и declare и unset и export. set принимает параметры для определения области и экспортируемости переменной:

# Define $PAGER global and exported, so this is like ``export PAGER=less``
set -gx PAGER less

# Define $alocalvariable only locally - like ``local alocalvariable=foo``
set -l alocalvariable foo

или для удаления переменных:

set -e PAGER

VAR=VAL операторы доступны в качестве переопределений среды:

PAGER=cat git log

Рыба не выполняет разбиение слов. После установки значения переменной, это значение остается неизменным, поэтому двойные кавычки при расширении переменных не являются такой же необходимостью, как в bash. 1

Например, вот bash

> foo="bar baz"
> printf '"%s"\n' $foo # will print two lines, because we didn't double-quote, so the variable is split
"bar"
"baz"

А вот рыба:

> set foo "bar baz"
> printf '"%s"\n' $foo # foo was set as one element, so it will be passed as one element, so this is one line
"bar baz"

Все переменные являются «массивами» (мы используем термин «списки»), и расширение переменной расширяется до всех её элементов, где каждый элемент является собственным аргументом (как в bash'овском "${var[@]}") :

> set var "foo bar" banana
> printf %s\n $var
foo bar
banana

Можно выбрать определенные элементы списка:

echo $list[5..7]
1

zsh также по умолчанию не выполняет разбиение слов (опция SH_WORD_SPLIT управляет этим)

Шаблоны (глобы)

Рыба поддерживает только * и ** шаблоны (и устаревший ? шаблон). Если шаблон не соответствует ни одному файлу, команда завершается ошибкой (как в bash'овском failglob), за исключением случаев, когда команда является for, set или count, или шаблон используется с переопределением среды (VAR=* command), в этом случае он расширяется до пустой строки (как в bash'овском nullglob варианте).

Глоббинг не происходит при расширении переменных, поэтому:

set foo "*"
echo $foo

не найдет ни одного файла.

Нет опций для управления глоббингом, поэтому он всегда ведет себя так.

Кавычки

Рыба имеет два типа кавычек: "" и ''. В двойных кавычках переменные расширяются, а в одинарных — нет.

Нет $'', вместо этого последовательности, которые должны преобразовываться, преобразовываются при отсутствии кавычек:

> echo a\nb
a
b

Обработка строк

В рыбе нет ${foo%bar}, ${foo#bar} и ${foo/bar/baz}. Вместо этого обработка строк выполняется встроенной командой string.

Специальные переменные

Некоторые переменные bash и их аналоги в рыбе:

  • $*, $@, $1 и так далее: $argv
  • $?: $status
  • $$: $fish_pid
  • $#: Нет переменной, используйте вместо этого count $argv
  • $!: $last_pid
  • $0: status filename
  • $-: В основном status is-interactive и status is-login

Замена процессов

Вместо <(command) рыба использует (command | psub). Нет эквивалента >(command).

Обратите внимание, что оба эти приема являются bash-истическими и большинство операций можно легко выразить без них. Например, вместо:

source (command | psub)

просто используйте:

command | source

так как функция source рыбы может читать из стандартного ввода.

Встроенные документы

В рыбе нет <<EOF «встроенных документов». Вместо:

cat <<EOF
some string
some more string
EOF

используйте:

printf %s\n "some string" "some more string"

или:

echo "some string
some more string"

Кавычки следуют через новые строки.

Тест (test, [, [[)

Рыба имеет совместимую с POSIX встроенную функцию test или [. Нет [[, и test не принимает == как синоним =. Однако она может сравнивать числа с плавающей точкой.

set -q может использоваться для определения того, существует ли переменная или имеет ли она определенное количество элементов (set -q foo[2]).

Арифметическое расширение

В рыбе нет $((i+1)) арифметического расширения, вычисления обрабатываются с помощью встроенной команды math:

math $i + 1

Она может обрабатывать числа с плавающей точкой:

> math 5 / 2
2.5

Подсказки

Рыба не использует переменные $PS1, $PS2 и так далее. Вместо этого подсказка — вывод функции fish_prompt, плюс функция fish_mode_prompt, если включен видо-режим, и функция fish_right_prompt для правой подсказки.

Например, вот относительно простая bash подсказка:

# <$HOSTNAME> <$PWD in blue> <Prompt Sign in Yellow> <Rest in default light white>
export PS1='\h\[\e[1;34m\]\w\[\e[m\] \[\e[1;32m\]\$\[\e[m\] '

и приблизительный эквивалент в рыбе:

function fish_prompt
    set -l prompt_symbol '$'
    fish_is_root_user; and set prompt_symbol '#'

    echo -s $hostname (set_color blue) (prompt_pwd) \
    (set_color yellow) $prompt_symbol (set_color normal)
end

Это демонстрирует некоторые различия:

  • Рыба предоставляет функцию set_color для форматирования текста. Она может использовать 16 именованных цветов и последовательности RGB (так что вы также можете использовать set_color 5555FF)
  • Вместо введения специфических эскейпов, как \h для имени хоста, подсказка представляет собой просто функцию, поэтому вы можете использовать переменные, например $hostname.
  • Рыба предлагает вспомогательные функции для добавления элементов в подсказку, например, fish_vcs_prompt для отображения систем контроля версий (git, mercurial, svn) и prompt_pwd для отображения сокращенного $PWD (домашний каталог пользователя становится ~ , и любой компонент пути сокращается).

По умолчанию подсказка достаточно функциональна, и ее код можно прочитать с помощью type fish_prompt.

В рыбе нет $PS2 для продолжения строк, вместо этого строки отступают, чтобы показать, что командная строка еще не завершена.

Блоки и циклы

Конструкции блоков в рыбе выглядят немного иначе. Все они начинаются со слова, заканчиваются end и не имеют второго слова начала:

for i in 1 2 3; do
   echo $i
done

# becomes

for i in 1 2 3
   echo $i
end

while true; do
   echo Weeee
done

# becomes

while true
   echo Weeeeeee
end

{
   echo Hello
}

# becomes

begin
   echo Hello
end

if true; then
   echo Yes I am true
else
   echo "How is true not true?"
fi

# becomes

if true
   echo Yes I am true
else
   echo "How is true not true?"
end

foo() {
   echo foo
}

# becomes

function foo
    echo foo
end

# (note that bash specifically allows the word "function" as an extension, but POSIX only specifies the form without, so it's more compatible to just use the form without)

В рыбе нет until. Используйте while not или while !.

Подоболочки

У bash есть функция под названием «подоболочки», где она запускает новый процесс оболочки для определенных задач. Эта оболочка будет независимой, и, например, любые изменения, которые она внесёт в переменные, не будут видны в основной оболочке.

Это включает в себя:

# A list of commands in `()` parentheses
(foo; bar) | baz

# Both sides of a pipe
foo | while read -r bar; do
    # This variable will not be visible outside of the while loop.
    VAR=VAL
    # This background process will not be, either
    baz &
done

Часто подоболочки путают с группировкой {}, которая не использует подоболочку. Для группировки можно использовать begin; end в рыбе:

(foo; bar) | baz
# when it should really have been:
{ foo; bar } | baz
# becomes
begin; foo; bar; end | baz

Конвейер будет просто выполнен в том же процессе, поэтому циклы while read могут устанавливать переменные за пределами цикла:

foo | while read bar
    set -g VAR VAL
    baz &
end

echo $VAR # will print VAL
jobs # will show "baz"

Подоболочки также часто путают с заменами команд, которые bash записывает как `command` или $(command), а рыба — как (command). Bash также использует подоболочки для их реализации.

Изоляцию обычно можно достичь, просто ограничив область действия переменных (с помощью set -l), но если вам действительно нужно запустить код в новой среде оболочки, вы всегда можете использовать fish -c 'your code here' для явного выполнения.

Встроенные команды и другие команды

К этому моменту становится ясно, что рыба делает больший упор на свои встроенные команды и внешние команды, а не на свой синтаксис. Вот некоторые полезные встроенные команды и их примерные аналоги в bash:

  • string - это заменяет большинство преобразований строк (${i%foo} и т.д.) и также может использоваться вместо grep и sed и т.п.
  • math - это заменяет $((i + 1)) арифметику и также может работать с числами с плавающей точкой и некоторыми простыми функциями (синус и аналогичные).
  • argparse - это может обрабатывать разбор опций сценария, для чего bash, вероятно, использовал бы getopt (zsh предоставляет zparseopts).
  • count может использоваться для подсчета вещей и, следовательно, заменяет $# и может использоваться вместо wc.
  • status предоставляет информацию о состоянии оболочки, например, является ли она интерактивной или каков текущий номер строки. Это заменяет $- и $BASH_LINENO и другие переменные.
  • seq(1) может использоваться в качестве замены для {1..10} расширения диапазонов. Если ваша ОС не поставляет seq, fish включает функцию замены.

© 2021 fish-shell developers
Licensed under the GNU General Public License, version 2.
https://fishshell.com/docs/3.3/fish_for_bash_users.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API