вторник, 27 марта 2012 г.

Обустройство консоли

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

Приглашение командного интерпретатора bash формируется на основе содержимого переменной окружения PS1. Если верить man-страницам, эта переменная может содержать любые строки, а также довольно большой набор специальных управляющих символов, которые при выводе приглашения будут превращены в актуальные данные. Так, например, в дистрибутиве Ubuntu содержимое переменной PS1 выглядит так:

'${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '



А при выводе на экран превращается во всем знакомую строку вида:

юзер@имя_хоста:текущий_каталог$

Нетрудно догадаться, что юзер здесь появляется за счет управляющего символа '\u', имя хоста — за счет '\h', а текущий каталог — это '\w'. Неуклюжая запись, содержащая в себе слова debian_chroot, это всего лишь индикатор того, находится ли пользователь в chroot-окружении. Такое лаконичное приглашение, конечно, удобно, но содержит далеко не всю информацию, которую bash способен отобразить. В его арсенале есть как минимум два десятка различных управляющих последовательностей, о которых многие пользователи даже не подозревают. Вот список наиболее интересных из них:
\d — текущая дата
\j — количество фоновых заданий
\A — текущее время
\! — номер команды в истории

Кроме того, в PS1 вполне можно использовать текущие переменные окружения, а если учитывать, что перед каждым выводом на экран PS1 перечитывается, то туда можно засунуть такие вкусности, как, например, статус последней выполненной команды (переменная $?), чтобы знать, было ли ее исполнение успешным.

Управляющий символ '\n' также допустим в PS1, поэтому приглашение к вводу можно сделать многострочным, а заодно визуально отделить его от остального текста (с помощью начальной пустой строки):

PS1='\n\w\n\u@\h:$?\$ '

Но и это еще не все. Пример с индикатором chrootокружения показывает, что в приглашении можно использовать вывод любых сторонних приложений, а это открывает просто безграничные возможности по его кастомизации. Например, следующим образом в приглашение можно добавить данные о текущей погоде, количестве непрочитанных писем в gmail и уровне сигнала Wi-Fi:

$ vi ~/.bashrc
# Google-погода
weather()
{
# Где мы?
local city="Moscow"
curl -s "http://www.google.com/ig/
api?weather=$city" | sed 's|.*<temp_c data="\
([^"]*\)"/>.*|\1|'
}
# Google-почта
unread_mail(){
# Имя пользователя и пароль (без @gmail.com)
local login="логин"
local password="пароль"
wget --secure-protocol=TLSv1 --timeout=3 -t 1 -q -O — https://${login}:${password}@
mail.google.com/mail/feed/atom --nocheckcertificate | grep fullcount | sed
"s/<fullcount>\(.*\)<\/fullcount>/\1/"
}
# Сигнал Wi-Fi
wifi(){
/sbin/iwconfig wlan0 | grep Quality | cut -d= -f2 | awk '{print $1}'
}
PS1='\n`weather`:`unread_mail`:`wifi`:\w\n\
u@\h:$?\$ '

Все это нужно поместить в конец ~/.bashrc и выставить на файл права 600, чтобы никто не смог подсмотреть пароли. Результат будет примерно таким:

-7:32:70/70:/usr/local
j1m@1313:0$
Раскрашиваем консоль

При работе в консоли пользователь часто получает большое количество никак не отформатированной информации. Порой выбрать в потоке данных действительно необходимое довольно сложно. Благодаря специальным непечатаемым escape-последовательностям мы можем изменить цвет и фон выводимых символов, чтобы облегчить восприятие данных.

Все escape-последовательности заключаются в \[\033[ и \], а после кода цвета должна еще стоять буква m. Все цвета расписаны в справочной странице. Например, черному соответствует 0;30, зеленому — 0;32, красному — 0;31, желтому — 1;33, белому — 1;37 и так далее. Чтобы в строке приглашения выводились имя системы (символ h) и логин пользователя (u), подсвеченные красным цветом, а текущий каталог — желтым (w), в конфиге ~/.bashrc заменяем значение переменной PS1 на следующее:

PS1="\[\033[0;31m\]\u@\h:\[\033[1;33m\](\w)[\033[0m\]\[\033[0m\]"

При необходимости через точку с запятой можно указать цвет фона. Для этой цели используются числа от 40 (черный) до 47 (белый).

PS1="[\033[32;40m\w\[\033[0m\]>"

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

local GRAY="\[\033[1;30m\]"
local NO_COLOUR="\[\033[0m\]"

Не забываем о том, что некоторые команды поддерживают цветной вывод. Проще это решить при помощи алиасов:

alias ls='ls --color=auto'
alias grep='grep --color=auto'

И так далее. За настройки цветов каталогов и файлов с разным расширением отвечает утилита dircolors, устанавливающая переменную LC_COLORS. Чтобы получить все значения, просто вводим:

$ dircolors --print-database

Использовав полученный результат как шаблон и сохранив его в / etc/DIR_COLORS (либо в персональном конфиге ~/.dir_colors), можно создать свою раскраску.

Программистам будет очень полезен cout (code.google.com/p/cout) — небольшой скрипт на Python, подсвечивающий вывод make, gcc, svn и diff. Скрипт не требует установки, просто скачиваем и распаковываем архив, а затем создаем псевдоним:

$ alias makec='cout data/make-gcc.cfg'

Теперь проверяем работоспособность, используя заранее подготовленный Makefile:

$ makec -f Makefile
Автодополнение bash

Одна из самых удобных функций, имеющихся в bash — автодополнение команд по клавише <Tab>. К этому быстро привыкаешь, и кажется, что улучшить уже ничего нельзя. Однако в разных дистрибутивах автодополнение работает по-разному.

Например, в современных Linux-дистрибутивах, ориентированных на обычного пользователя, bash не только дополняет саму команду, но и предлагает дополнительные параметры. Однако в Gentoo и производных (вроде Calculate Linux) такого нет. Здесь приходится помнить все параметры назубок. Как такое может быть? Некоторые разработчики дистрибутивов используют патченые версии bash?
На самом деле, возможность автодополнения в bash — расширяемая функция. За необходимую функциональность отвечает встроенная команда compgen, генерирующая соответствующие списки. Все настройки производятся в файле /etc/bash_completion (или пользовательском ~/.bash_completion), хотя в некоторых дистрибутивах можно найти целый каталог /etc/bash_completion.d, в котором обычно собраны настройки, специфичные для отдельных программ.

В самом простом случае файл содержит программу и указания для bash по дополнению имен файлов.

Например, чтобы MPlayer предлагал пользователю в качестве автодополнения только файлы с расширением avi и mpg, пишем такое правило: complete -f -X ‘!*.@(avi|mpg|AVI|MPG/so)’ mplayer Но это самый простой вариант, ведь MPlayer имеет большое количество дополнительных параметров, а значит, ему потребуется описать шрифты, звуковые файлы, субтитры и так далее. Все это легко решается при помощи оператора case. Поддерживаются регулярные выражения, что немного упрощает создание правил.

Обычно майнтейнеры конкретного пакета сами составляют списки параметров программы для bash_completion. Никаких чудес здесь нет.

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

COMPREPLY=( $( compgen -W 'c t x u r d A' -- "$cur" ) )

Как видишь, мы просто перечислили все параметры, и теперь в процессе ввода bash сам выдаст этот список. Команда compgen имеет ряд параметров. Так '-b' позволяет получить список встроенных команд оболочки, '-c' — имена команд, '-v' — имена переменных и так далее. Все подробности можно найти в man-странице bash, в секциях complete и compgen.
Продвинутые настройки

Bash — довольно развитый командный интерпретатор, поддерживающий кучу разных настроек. Причем из этих настроек можно получить гораздо больше профита, чем из настроек поведения терминала, выполненных с помощью утилит setterm и stty. Список всех возможных опций можно посмотреть командой «shopt -p» (shopt — сокращение от Shell Options). Приведем самые интересные из них:
autocd — если эта опция включена, то можно просто написать путь к каталогу (опустив команду cd), чтобы в него переместиться;
cdspell — bash будет пытаться исправлять простые опечатки (например, /ect/init.d вместо /etc/init.d) в аргументах команды cd;;
checkjobs — не дает выйти из консоли, пока в ней есть выполняющиеся задания;
cmdhist — объединение многострочных команд в одну строку так, чтобы тебе было проще искать их в истории;
dirspell — исправление небольших ошибок в написании имени директории при автодополнении;
globstar — позволит использовать конструкцию вида **, обозначающую «все файлы, начиная с текущего каталога, рекурсивно»;
Очень удобный новый wildchar — например, данная конструкция отобразит все mp3 в текущем и вложенных каталогах:

$ ls **/*.mp3

Согласись, это гораздо короче и удобнее, чем:

$ find ./ -name "*.mp3" -type f -print

Устанавливаются опции следующим образом:

$ shopt -s autocd cdspell checkjobs cmdhist dirspell globstar

Кроме того:

1. Bash умеет сокращать путь к текущему каталогу в приглашении, если он становится слишком длинным. Для управления этой функцией предусмотрена переменная окружения PROMPT_DIRTRIM. При превышении уровня вложенности каталогов, указанного в этой переменной, путь будет сокращен. Пример использования:

$ export PROMPT_DIRTRIM=3

2. Bash поддерживает «умный» метод помещения команд в историю, позволяя освободить ее от банальностей вроде ls. В историю не будут попадать дубликаты и команды ls, bg, fg, exit после выполнения следующей команды:

$ export HISTIGNORE="&:ls:[bf]g:exit"

3. Bash умеет делать так, чтобы команды, выполненные с использованием sudo, автоматически попадали в файл истории root'а и не засоряли историю пользователя. Просто добавь следующую строку в файл /etc/bash.bashrc:

export HISTFILE=$HOME/.bash_hist-`whoami`
Индикатор прогресса

Отсутствие индикатора прогресса у большинства консольных утилит — одна из главных проблем для тех, кто часто работает в консоли. И хорошо, если под рукой есть mc, который многие так и используют, чтобы получить окошко с прогрессом. А что если это голая консоль, а тебе требуется сохранить бэкап на флешку, смонтированную в режиме sync? В этом случае тебе поможет rsync, который хоть и несколько замедляет процесс копирования, но зато обеспечивает вывод на экран шкалы прогресса. Помещаем в ~/.bashrc следующую строку:

alias cpr='rsync --progress'

И используем команду cpr вместо cp:

$ cpr file1 file2

Если добавить опцию '--remove-source-files', то исходные файлы будут удалены (правда, следует помнить, что в пределах одной файловой системы mv гораздо быстрее rsync). Единственный минус — прогресс отображается для каждого файла в отдельности, общий прогресс увидеть нельзя.

Чтобы увидеть ход выполнения, например, при создании архива, можно использовать утилиту pv (Pipe Viewer). Технически она представляет собой замену стандартного cat, способную не только тупо копировать байты на выход, но и показывать прогресс этой операции. Например:

$ tar -czf — /path/to/dir | pv > /path/to/archive.tgz
758MB 0:01:29 [8,48MB/s] [ <=>

Уже хорошо. Но не хватает времени завершения. Для этого надо передать утилите pv размер каталога (в байтах) с помощью ключа '-s':

$ tar -czf — /path/to/dir | pv -s $(du -sb /path/to/dir | grep -o '[0-9]*') > /path/to/archive.tgz
461MB 0:00:21 [ 32MB/s] [=======================================> ] 60% ETA 0:00:13

Каждый раз набирать такую конструкцию не очень удобно, лучше сделать алиас.
Закладки каталогов в консоли

При выполнении операций администрирования приходится часто переходить по каталогам файлового дерева. Bash поддерживает ряд сокращений (например, чтобы вернуться в домашний каталог, просто вводим «cd», в предыдущий каталог — «cd -»), но этого мало. Конечно, можно использовать псевдонимы (aliases), вроде:

alias cdwww='cd /var/www'

Но этого все равно бывает недостаточно в том случае, если список каталогов большой. И главное — использование алиасов не очень удобно. Так, чтобы создать новый псевдоним, нужно вручную прописать его в ~/.bashrc и перезапустить терминал. Небольшой скрипт Directory Bookmarks for BASH (dirb.info/bashDirB) расширяет набор сокращений, позволяя на лету создавать закладки на нужные каталоги и переходить в них короткой командой.

Скачиваем:

$ wget -c http://www.dirb.info/bashDirB -o ~/.bashDirB

И добавляем в файл ~/.bashrc строку:

source ~/.bashDirB

Теперь каждая новая сессия будет поддерживать закладки. Переходим в нужный каталог и сохраняем его в закладку:

$ cd /var/www
$ s www

После этого будет создан файл ~/.DirB/www, содержащий ссылку на закладку. Теперь, чтобы вернуться в указанный каталог с любого места файловой системы, достаточно ввести в консоли «g www». Аналогичным образом можно создавать любое количество закладок. Но это не все параметры. Например, параметр «p» позволяет запомнить последние перемещения и выводит их в консоли:

$ p www
/var/www
~

И, наконец, команда s1 позволит просмотреть листинг закладок. Для удаления закладки используем ключ '-r'.

Также следует знать, что bashDirB модифицирует переменную PS1 таким образом, что в приглашении выводится время и номер текущего каталога в history. Если тебя это не устраивает, просто закомментируй соответствующую строку в скрипте.

В качестве альтернативы bashDirB можно использовать apparix (micans.org/apparix), предлагающий три команды: bm (создание закладки), to (переход к закладке) и portal (добавление подкаталогов в закладки). Помимо bash также поддерживается csh. Пакет доступен в репозитарии Debian/Ubuntu и некоторых других дистрибутивов.
Фортунки

В некоторых Linux-дистрибутивах после запуска консоли выводится небольшая цитата. Практической пользы от нее вроде и нет, но небольшое шуточное высказывание повышает настроение и настраивает на рабочий лад. Тематические пакеты с базами высказываний называются fortunes, а сами цитаты — фортунками.

За несколько десятков лет в Сети появилось большое количество сборников цитат, которые легко интегрируются в консоль. Чтобы установить их в Debian или Ubuntu, достаточно ввести команду:

$ sudo apt-get install fortunes fortunes-debianhits fortunes-ubuntu-server fortunes-min fortune-mod fortunes-ru

Последние два пакета содержат большое количество афоризмов на русском. Кроме этого, в интернете доступны и другие русскоязычные сборки фортунок, найти которые очень просто — достаточно вбить в Гугле fortunes-ru и получим несколько десятков ссылок (например, избранные цитаты с сайта linux.org.ru:lorquotes.ru/fortunes.php).

После установки необходимо настроить вывод цитат в консоль. В самом простом случае достаточно прописать в конфиг ~/.bashrc всего одно слово:

$ echo "fortune" >> ~/.bashrc

Далее следует перезапустить терминал или перезагрузить файл настроек (команда «source ~/.bashrc»). Cписок выводимых категорий фортунок можно получить, введя:

$ fortunes -f

После установки все фортунки помещаются в один из подкаталогов /usr/share/games/fortunes, откуда их и забирает программа. В случае необходимости при помощи ключа '-m' можно указать шаблон фортунок, которые будут выводиться. После добавления своих фортунок следует использовать утилиту strfile для создания индекса (strfile файл_фортунок).

При желании можно грабить RSS-новости, твиты, прогноз погоды или котировки валют с любого сайта, выводя их в качестве фортунок. Хотя для этого мне больше нравятся аналоги fortunes — пакеты cowsay и xcowsay. Сowsay представляет собой приложение на Perl, которое выводит изображение говорящей или думающей коровы, нарисованной ASCII-символами.

$ sudo apt-get install cowsay xcowsay

По умолчанию корова не знает, что сказать, умную мысль ей надо подкинуть. Например, выведем uptime:

$ uptime | cowsay

Или фортунку (так реализовано в Linux Mint):

$ cowsay 'fortune'

Кроме стандартной коровы доступны и другие персонажи, соответствующие названию файлов в подкаталоге /usr/share/cowsay/ cows. Вызвать их можно при помощи параметра '-f'. Также ряд параметров изменяют внешний вид коровы: '-t' — усталая корова, '-p' — параноидальная, '-w' — обалдевшая и так далее. Чтобы автоматизировать процесс, заносим строку запуска в ~/.bashrc:

COWDIR=/usr/share/cowsay/cows/;
COWNUM=$(($RANDOM%$(ls $COWDIR | wc -l)));
COWFILE=$(ls $COWDIR | sed -n ''$COWNUM'p'); fortune |
cowsay -f $COWFILE
Заключение

Собственно, это все. Следуя рекомендациям, описанным в статье, ты сможешь сделать работу в консоли гораздо более удобной и продуктивной, а также освободить время для более важных занятий.
Перенос директории dotfiles

Перенос директории dotfiles с одного компа (IP-адрес 192.168.1.1, порт 10000) на другой при помощи netcat и pv:

host1$ tar -cf — dotfiles | pv | nc -l -p 10000 -q 5
host2$ nc 192.168.1.1 10000 | pv | tar -xf

В случае, если host1 работает под управлением OpenBSD, команда должна выглядеть так:

obsdhost1$ tar -cf — dotfiles | pv | nc -l 10000
Пишем в твиттер легко и непринужденно

Простая функция, отправляющая сообщения в твиттер:

$ vi ~/.bashrc
twit()
{
curl --basic --user юзер:пароль --data
status="$*" 'http://twitter.com/statuses/update.xml' -o /dev/null;
}

Использовать так:

$ twit 'Привет из консоли'

Не забываем про 140 символов.
How much is the FISH?

Новичкам в консоли следует внимательно посмотреть в сторону альтернативного командного интерпретатора под названием FISH (Friendly Interactive Shell). Его преимущества перед bash довольно внушительны. Fish на полную катушку использует возможность управления цветами терминала. Он оснащен гораздо более мощной системой автодополнения, которая выводит на экран не только списки каталогов, аргументов и имена команд, но и массу другой полезной информации (например, рядом с каждой опцией помещается описание того, что она делает). В Fish встроена очень хорошая система подсказок, так что если ты допустишь ошибку, то получишь обширное разъяснение того, что произошло, и способы обхода проблемы. Наконец, скриптовый язык Fish гораздо проще и логичнее стандартного языка sh.
Info
Во FreeBSD использовать rsync для получения прогресса копирования файлов нет смысла. Можно просто нажать <Ctrl+T> во время работы команды cp, и она сама выдаст прогресс операции на экран.
Чтобы сделать man-страницы цветными, установи пакет most с помощью пакетного менеджера и добавь строку «export MANPAGER="/usr/ bin/most -s» в файл ~/.bashrc.
Команда «stty -echo» отключает вывод в терминал того, что набирается на клавиатуре. Подобное поведение можно наблюдать при вводе пароля при логине в терминале.
Убрать курсор из терминала и выключить гашение экрана можно с помощью команд «setterm -cursor off» и «setterm -blank 0».
Links
Сайт разработчика fortune-mod-ru: jack.kiev.ua/fortunemodru
Сайт проекта bashDirB (Directory Bookmarks for BASH): dirb.info/bashDirB.

Комментариев нет:

Отправить комментарий