Оболочек для unix-like систем расплодилось много: sh, bash, dash, zsh. Выбрать тот самый из всего зверинца очень сложно. В этой маленькой блогозаписи я хочу осветить один прекрасный продукт, который развивается около 8 лет.
fish - это не просто yet another shell, за 8 лет они сделали действительно удобный и гибкий шелл. У них в документации есть фраза «unlike other shells» под которой подписаны функции, уникальные для этой оболочки. Сначала я напишу о них, а уже потом выскажу свое мнение.
Встроенная документация
В fish есть встроенная документация, достаточно ввести комманду:
$ help
И в браузере откроется отформатированный документ со всеми описаниями его внутренностей.
Перенаправление вывода
В других шеллах перенапрявлять вывод можно с помощью операторов <
и >
, в fish пошли дальше и сделали такой функционал и для ошибок:
$ grep fish < /etc/shells > ~/output.txt ^ ~/errors.txt
Переменные
В fish нет синтаксиса для установки значений переменным, для этого сделали команду set
:
$ set name 'Mister Noodle'
$ echo $name
Mister Noodle
Статус завершения
Статус завершения программы хранится в переменной $status
, а не в $?
:
$ false
$ echo $status
1
Переменные окружения
Команды для установки переменных окружения export
нет, вместо этого можно использовать set
с аргументом -x
или --export
:
$ set -x MyVariable SomeValue
$ env | grep MyVariable
MyVariable=SomeValue
Вы так-же можете очищать эти переменные:
$ set -e MyVariable
$ env | grep MyVariable
(no output)
Подстановка
В других оболочках, для подстановки в команду, выражение оборачивают в кавычки; в fish вы можете использовать для этого круглые скобки:
$ echo In (pwd), running (uname)
In /home/tutorial, running FreeBSD
$ set os (uname)
$ echo $os
Linux
$ touch "testing_"(date +%s)".txt"
$ ls *.txt
testing_1360099791.txt
Комбинаторы
Вместо &&
и ||
в fish есть and
, or
и not
:
$ cp file1.txt file1_bak.txt; and echo "Backup successful"; or echo "Backup failed"
Backup failed
Функции
Для доступа к аргументам функций используется переменная $argv
, вместо $1
, $2
, $3
и т.д.
$ function say_hello
echo Hello $argv
end
$ say_hello
Hello
$ say_hello everybody!
Hello everybody!
$ function my_name_is
echo $argv[1]
end
$ my_name_is Yuri Artemev
Yuri
Prompt
В fish нет переменных для установки prompt, таких как PS1. Для этого есть функция fish_prompt
, которую вы можете переопределить:
$ function fish_prompt
echo "New Prompt % "
end
New Prompt % _
А теперь немного отсебятины
Первое, что мне не понравилось – это установка переменных. В fish нельзя написать так:
$ RAILS_ENV=test rake db:migrate
Вместо этого приходится устанавливать переменные с помощью команды set
или делать это после самой команды:
$ rake db:migrate RAILS_ENV=test
Забудьте о Ctrl + R
, в этой оболочке нет привычного поиска, в fish все круче – вы просто пишете команду и тут же серым подставляется первое совпадение, если не подошло – бродим по истории с помощью стрелок вверх и вниз, все очень просто.
Массивы – они мощные:
$ set ary 1 2 3 4 5 6 7 8 9 hello
$ echo $ary[1]
1
$ echo $ary[-1]
hello
$ echo $ary[1..5]
1 2 3 4 5
$ echo $ary[-1..-3]
hello 9 8
$ echo $ary[-1..1]
hello 9 8 7 6 5 4 3 2 1
$ count $ary
10
$ set ary[5] 50
$ echo $ary
1 2 3 4 50 6 7 8 9 hello
$ for v in $ary
echo $v
end
1
2
3
4
50
6
7
8
9
hello
Есть подсветка синтаксиса, есть команды prevd
и nextd
для путешествия туда и обратно по директориям, а еще можно делать крутые темы.