UNИX, весна 2008, 09 лекция (от 09 апреля)
Материал из eSyr's wiki.
Диктофонная запись: http://esyr.org/lections/audio/uneex_2008_summer/uneex_08_04_09.ogg
Лектор был всю прошлую неделю в Якутске. Там нашёл линуксоида, который самостоятельно перевёл контору на Линукс, зная что до ближайшего другого линуксоида 600 километров...
Про линукс в школах ... Набор программ "Первая помощь" это чемодан с 56 дисками, в том числе 8 дисков "Visual Basic Suite". А в Альте всё необходимое помещается на один DVD.
Господа из тех, кто лучше знаком с предметом: проявляйте активность и говорите, о чём рассказывать заранее.
Маленькое дополнение к пред. лекции о file name generation: в zsh есть **, соответственно **/*.c развернётся во все *.c во всех подкаталогах текущего каталога.
Тема: редактирование ввода
Шелл един в трёх лицах, у него 3 ипостаси: шелл это оболочка, шелл это интегратор, шелл это текстовый интерфейс с человеком. То, как последнее можно сделать более удобным, лектор и попытается обозреть. Одним шеллом это не ограничивается, и не с него начинается. Начинается всё с терминала, который не просто устройство для ввода и вывода человекочитаемых байтов, он их ещё немного по ходу дела сам обрабатывает (cooked-режим). Это позволяет обрабатывать Ctrl-c, и другие в некоторые специальные сигналы. Почему так происходит? Потому что мы stty настроили таким образом, что нажатие Ctrl+C приведет к тому, что процесс, привязанный к этому терминалу по вводу получит не очередные байтики на вход, а сигнал SIGINT. Разговор о том, что помоимо превращения некоторых комбинаций в сигналы [я не уверен почему-то, что это делает именно терминал, может быть shell? Нужна бы схемка процессов этих всех, где там терминал? %) --PavelSutyrin], терминальная линия обеспечивает ещё некоторые вещи. Например, преобразование символов конца строки. Например, в принтерах традиционно требуется пара символов: возврат каретки (carriage return, CR), и перевод строки (line feed, LF), т.е. CR-LF, а в файлвах просто LF. И терминал этим занимается. В частности, в терминале linux уже определно три символа для редактирования: удаление последнего символа, удаление последнего слова, удаление всей строки. Команда stty выведет по этому поводу обозначения ERASE (символ), KILL (строка), WERASE (слово). Соответственно, обычно это Backspace, Ctrl+U, Ctrl+W. Проблема с BS, который в разных терминалах связан с разным кодами клавиш, в частности, одно из исключений --- терминал Linux. Соответственно, с этим BS возникнет ряд проблем, например, в vim это решили тем, что ручками вбили все возм. варианты и их можно определенной командой переключать. Кроме того, чтение line-buffered, то есть программе не придут данные, пока вы не нажмёте конец строки (ещё один спецсимвол, воспринимаемый терминалом), и редактируя эту строку, уже имеете три команды редактирования. Это не просто примитив, а минимализм устрашающий. Кстати, sh и ash не имеют встроенных средств ред. строки в принципе. Это дисциплинирует польз. --- если команда слишком длинная, то это значит, что надо открыть текстовый редактор и написать скрипт, хотя, конечно, сейчас так никто не делает.
Есть очень большой раздел про редактирование командной строки. Есть такая библиотека libreadline -- редактор командной строки. На её основе построены многие утилиты (в т.ч. в GNU, и не только), предоставляющие пользователю интерфейс командной строки. Тот же python, будучи запущен в интерактивном режиме, написан с libreadline. Для того, чтобы освоить весь readline, читайте ман, обычно именно благодаря ему при редактировании строки у нас работают стрелочки, Home, End. libreadline имеет свой настроечный файл, который наз. .inputrc. Его будет учитвывать все программы, использующая libreadline, это удобно. Например, лектор в нём настроил переход вперед и назад на одно слово на PgDn и PgUp соответственно, и это работает теперь во многих программах, он всем рекомендует.
Что такое .inputrc? Это привязка клавиш, которые нажимаете на клавиатуре (например, стрелочек) к командам текстового редактора, редактора командной строки. Вы сами всё можете перенастроить в inputrc. Команд этих в баше в районе полусотни. Что это за команды помимо команд перемещ. по строке?
- Перемещение на разные единицы строки
- Команды редактирования (например, изменить регистр всех символов некоторого слова, если мы забыли отжать CapsLock)
- Глупости типа команды переставления местами символов
Реально редактирование символов устроено на уровне vi. Кстати сказать, для больших фанатов vi, а также для тех, у кого плохо с ... обратите внимание на то, что в отл. от обычных буковок (когда клавиатура передаёт один байтик) при нажатии на всякие клавиши, не являющиеся обычными, типа стрелочек, фукнциональных клавиш, возвращ. не один символ, а сразу несколько. Это сделано по аналогии с терминалом, с управл. последовательностями. Например, перемещение в начало ... --- ^]]A, где ^] --- это обозначение для Ctrl+], он же Esc. (Ctrl срезает 6-й бит от кода ], получается код ^]). В terminfo хранится именно то, какие управляющие последовательности посылаются при нажатии тех или иных клавиш на клавиатуре. Есть программа ...dump, начинаете нажимать на кнопки и смотрите на дамп. Вот эти вот последовательности можно забиндить в .initrc на выполнение команд в readline.
Есть встроенная в шелл команда bind, которая позволяет на ходу это записать. Далеко не все функции, которые есть в бинде, относятся к функциям именно редактирования командной строки. Например, есть такая отдельная и совершенно естественная для польз. штука, как работа с историей. Лектор не зря при рассказе не упоминал про стрелки вверх/вниз, это уже свойство редактора, в котором вы работаете. То есть, это требует от шелла сущей безделицы --- где-то хранить команды и осущ. по ним поиск. Есть обычное пролистывание, есть также поиск: по умолчанию есть ^R (reverse search), и это возм. поискать в истории команд подстроку. Например, Дима Левин, когда ему пришла в голову команда, а потом решил её не выполнять, он ставит перед ней решёточку, и жмёт ентер, а потом находит её по ^R. Разумеется, поиск и в другую сторону работает. Про историю надо знать три важные вещи:
- по умолчанию историю выключают. История ваших команд призрачный, но security flaw. Вообще говоря, поднимаясь на уровень достаточной параноидальности, историю команд лучше хранить в памяти, а на диск не писать. История может храниться в файле, размер файла задаётся в строках в переменной HISTSIZE. Удобно, когда можно по какому-то ключевому слову вспомнить длинную строку, которая набиралась вчера.
Что ещё можно вспомнить из команд редактирования? Лектор не знает, есть ли это в баше, но в zsh есть фича, которая позволяет сделать inplace file name generation. Для чего это нужно: чтобы ручками подредактировать, например, когда мы хотим применить какую-то команду ко всем файлам,оканчивающимся на .c, кроме одного. Тогда после раскрытия шаблона *.c можно из него его удалить.
Ещё одна главная вещь: достраивание. Допустим, мы хотим открыть файл /usr/share/doc/voodoo/README. В командной строчке никому не хочется писать имя файла длиной в пять шагов. поэтому, вместо этого можно использовать шаблон, который сам по себе короче, но раскроется в итоге в один этот файл: /u*/sh*/doc/vo*/RE*. Но какая проблема с таким FNG? Проблемы две: строчка /u*/sh*/doc/vo*/RE* читается намноого хуже. Второе --- не факт, что этому шаблону удовлетворяет всего один файл. Но помнить имена всех файлов во всех каталогах человеку невозможно. Поэтому неплохо бы процесс раскрытия шаблона контролировать. Делается это следующим образом: нажали таб и шелл достроил. Это то самое, о чём всегда мечтали. При этом процесс контроллируемый и последовательный. Это резко отличается от того, когда написали шаблон и посмотрели, что получается. Кроме того, могут быть ветвления. Эта проблема процедурой достраивания также решается. Если упираетесь в ветвление, например, если в /usr/share/doc есть каталоги voodoo и voobla, то он достроит voo и пискнет. А дальше, в зависимости от крутизны шелла, могут быть варианты. Может быть сразу начнёт перебирать варианты, может после второго шага, может список показать. Соответственно, ответственность переваливается на пользователя, ибо думать должен человек, а не машина. И человек уже решает, что строить дальше.
Использование достраивание сокращает время в разы. Кроме того поведение достраивания в случае неоднозначности настраиваемо. По умолчанию баш пищит, потом перебирать начинает.
Достраивание контекстнозависимое, например в случае с echo $PA будет работать подстановка имени переменных. Возможно, в баше есть другие вариант достраивания. Но в zsh оно устроено так, что святых выноси. Для польз. это выглядит след. образом: достраивание в zsh настолько контекстно, что он разбирается в том, к какой команде производится достраивание.
Если некую задачу по написанию строки можно доверить компьютеру, можно доверить компьютеру.
Лектор не знает, рассказывал ли это Наану, но в виме это тоже есть. Там есть 6 или 7 разных достраиваний
- По именам файлов
- По словам в тексте
- По спец. списку ключ. слов
- По словарю для работы с конкретным ЯП
- По чёрт ещё знает чему
- ^X^F --- достраивание по именам файлов
- ^X^P, ^X^N --- достраивание по словам внутри текста
Что ещё предусм. в шелле на предмет редактирования командной строки.
- ^]_ --- позволяет в шелле подставить последнее слово предыдущей команды. Полезно при обработке файла. Можно множитель масштабный приклеивать.
Есть ещё vi-mode, помогает при извращённом терминале.
Ещё, чем в полож. сторону отличается zsh от bash. В readline нельзя привязать команду ридлайна не к конкретной esc-последовательности, а к терминфо. А в zsh используется свой line editor, и в bindkey это можно сделать.
bindkey `echo tc kP` prev-word
Алиасы
Это шеллскрипты для бедных. Возможность определить некий укороченный вариант команды. Например
alias rm='rm -i'
Необязательно переопределять команду:
alias l='ls -FAC'
Рекурсивного подставления в алиасе не происходит, но происходит вложенная подстановка
Заменяется слово. Фактически, добавляете новую команду.
Стартовые сценарии
При старте было бы неплохо вписать алиасы, настр. переменых, и так далее. У каждого шелла есть набор сценариев, которые выполн. по умолчанию.
|
|