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*. Но какая проблема с таким filename generation? Проблемы две: строчка /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'

Рекурсивного подставления в алиасе не происходит, но происходит вложенная подстановка

Заменяется слово. Фактически, добавляете новую команду.

Стартовые сценарии

При старте было бы неплохо вписать алиасы, настр. переменых, и так далее. У каждого шелла есть набор сценариев, которые выполн. по умолчанию.


UNИX, весна 2008


Лекции

01 02 03 04 05 06 07 08 09 10 11 12 13 14


Календарь

Февраль
13 20 27
Март
05 12 19 26
Апрель
02 09 16 23 30
Май
07 14
Семинары

01 02 03 04 05 06 07


Календарь

Март
21
Апрель
04
Май
16 30
Июль
11 18
Август
15


Эта статья является конспектом лекции.

Эта статья ещё не вычитана. Пожалуйста, вычитайте её и исправьте ошибки, если они есть.
Личные инструменты
Разделы