учебники, программирование, основы, введение в,

 

Интерфейс

Что такое удобство?
В лекции, посвященной операционным средам, мы отмечали, что главное требование к ОС - это требование к интерфейсу системы, иными словами, к способу взаимодействия человека и машины в человеко-машинной системе. Именно от того, как пользователю предлагается "общаться" с компьютером, зависит его субъективное мнение о системе вообще. Причем в случае системы проективной, а значит - познаваемой, он может весьма неплохо представлять и что происходит в машине между сеансами взаимодействия, и чем продиктован тот или иной предлагаемый вид интерфейса - и все равно будет недоволен, если работать с системой "неудобно".
С этим "неудобно" следует обращаться предельно осторожно. С одной стороны, удобство - понятие субъективное. Нет возможности организовать интерфейс так, чтобы удобно было всем. Кое-каких успехов на этом поприще можно добиться в процедурных системах. Для начала взаимодействие с пользователем надо организовать так, чтобы оно как можно больше походило на работу с некомпьютерным, привычным инструментом (например, рисовать на графическом устройстве кнопки, задвижки, переключатели и пр.). Это возможно, потому что, согласно принципам организации процедурных систем, разговор с пользователем должен идти на языке прикладной области, частью которой этот привычный инструмент и является.
Смоделированные компьютером "инструменты" лишены многих естественных ограничений, что были у их физических прототипов, и удобство пользователя будет в некоторых случаях поистине несравненным (не трещит! не чадит! работает быстро!). Наконец, обратимость изменений объекта (за счет восстановления из резервной копии) позволяет заменить принцип "семь раз отмерь - один раз отрежь" другим: "семь раз отрежь - шесть раз undo".
Организация подобного рода интерфейса требует, как правило, значительных ресурсов для имитации пользовательского инструмента, и многие требования, предъявляемые компьютеру, оказываются требованиями интерфейса, а не самой пользовательской задачи. В первую очередь это относится к системам с непременным графическим интерфейсом, в которых даже для отправки текстового сообщения требуются устройства графического ввода и вывода: мышь, видеоадаптер, графический дисплей. Причем последние должны обладать определенными техническими характеристиками.
Погоня за удобством вполне естественна для процедурных систем, ориентированных, как мы помним, на немедленное освоение. Однако в проективных системах такой подход к организации интерфейса, скорее всего, неприемлем. Тут возникает необходимость взглянуть на вопрос с другой стороны, попытаться объективно выяснить, что такое субъективное понятие "удобство". Если судить по результату, интерфейс тем удобнее, чем меньше пользовательских и машинных ресурсов регулярно расходуется при решении задачи. Слово "регулярно" подчеркивает тот факт, что в проективной системе решению задачи обычно предшествует период освоения, когда и затрачивается главный пользовательский ресурс - время. Но З гарантирует нам, что так понимаемое удобство не пострадает: ведь освоение происходит однократно, а проективное решение задачи само является машиной для решения целых классов задач. Если пользователь уже решил мыслительную задачу, а значит, завершил основную часть своей работы, долг системы - предоставить ему интерфейс, удобный для быстрой и надежной формализации решения и для передачи его машине в качестве проекта. Можно сказать, что интерфейс удобен, если он не противоречит принципам построения системы.
Требования к интерфейсу UNIX
Как устроен интерфейс, т. е. основной канал взаимодействия между человеком и машиной, в UNIX?
Элементарные - а значит, самые распространенные - пользовательские действия должны быть реализованы как можно проще. Чем меньше пользователь тратит времени на элементарные действия, чем меньше ему приходится их контролировать, тем более свободен он для решения основной - мыслительной - задачи (работает З). Подобный подход может завести довольно далеко, в том числе и от действительного удобства, однако У всегда будет на страже, не давая перегружать диалог неудобоваримыми сокращениями и магическими знаками. Идеальное устройство окружения (подмножества используемых элементов интерфейса) должно быть таким, чтобы для решения каждой конкретной задачи пользователь основную часть инструментария знал, а правила применения некоторых специфических инструментов подглядел в руководстве.
Из чего сразу следует, что операция "подглядел в руководстве" - как раз одно из распространенных пользовательских действий, и она должна быть организована удобным для пользователя способом. Этого и следовало ожидать, раз уж первым принципом построения проективных систем мы выбрали И. Тут уж места для объективности и того меньше, однако стоит заметить, что организация альтернативного интерфейса для просмотра документации умножит количество сущностей и в системе, и в голове пользователя (что противоречит не только У, но и У. Оккаму). Было бы неплохо и командовать системой, и получать от нее необходимую информацию одними и теми же интерфейсными средствами.
Превращение элементарных пользовательских действий в знак ни в коей мере не должно мешать реализации сложных, структурированных действий. В конце концов, именно они суть решения пользовательских задач, именно из-за них и затевалась организация диалога человека и машины. Пользователь должен не только иметь возможность решить любую свою задачу, но и сделать это аккуратно, быстро, и опять-таки с максимальным удобством. Для чего (см. "Следствие 1" в лекции 2) необходим гибкий инструментарий достаточно высокого уровня.
Как ни странно, условие использования для такого интерфейса минимального количества дополнительной аппаратуры оказывается выполнимым. В компьютере есть устройства передачи данных? Замечательно! Давайте воспользуемся одним из них для управления системой. Какими дополнительными способностями такое устройство должно обладать? Почти никакими. Пускай только умеет передавать байты. К линии, по которой это устройство обменивается данными с внешним миром, присоединяется терминал (т. е. оконечное устройство, умеющее обмениваться информацией с человеком). Все. С системой можно работать. Подробнее о терминалах рассказано в лекции 8.

Командная строка

Логичным ответом на все четыре принципа построения проективной системы вместе с перечисленными требованиями стал интерфейс командной строки. Это такой способ взаимодействия человека и машины, при котором пользователь вводит с терминала текстовую команду системе, а система ее выполняет, отчитываясь о работе также в текстовом виде. Пользователь этот отчет читает, соображает, принимает решение (мы имеем право требовать от пользователя некоторой твердости духа, гарантированной О) и вводит новую команду ... и так до победного конца. Этот способ не противоречит сказанному выше и при грамотной организации труда весьма удобен для взаимодействия с проективными системами.
Интерпретатор командной строки в UNIX - shell (в русских переводах - "оболочка") - типичная программа этого рода. Вернее, семейство программ, потому что (как это часто бывает в UNIX) на разные вкусы существуют по-разному оформленные решения. Можно даже сказать, что терминал плюс командный интерпретатор UNIX и есть интерфейс командной строки, прочие же системы лишь с той или иной долей остроумия пародируют его.
Было бы нерационально для каждого элементарного пользовательского действия заготавливать еще одну команду (как непременно случится, если пользовательские действия будут наглядно представлены в виде изображений). Это означало бы нарушение У в самой грубой форме. Проективная система ориентирована на создание решений, а не на поиск, и гораздо правильнее давать человеку в руки инструмент решения класса задач, тогда свою задачу человек решит, управляя этим инструментом.
Таково понимание командной строки в shell и UNIX. Вводимая пользователем строка (напомним, что обмен данными - только текстовый) воспринимается интерпретатором как последовательность "слов", разделенных пробелами и/или символами табуляции; об этом подробнее рассказано в лекции 8. Первое слово строки - собственно команда (ей может предшествовать несколько присвоений переменным окружения этой команды каких-нибудь значений, подробнее о переменных окружения рассказано в лекции 11), последующие - передаваемые ей параметры (arguments). Часто вместо "параметры" говорят "аргументы". Выходит, что мы не просто командуем машиной, но и аргументируем свои решения. Параметры видоизменяют работу команды; иными словами, при помощи параметров пользователь выделяет из всего класса решаемых командой задач одну, а также описывает конкретные исходные данные. Например, команда shutdown выполняет останов системы. Если не указывать никаких параметров, останов начнется через пять минут, в течение которых shutdown предупреждает об этом всех работающих в системе пользователей. А вот команда shutdown now приступит к останову системы немедленно.
Чтобы не запутаться в терминологии, припомним главу 5, в которой говорилось об утилитах. Командный интерпретатор самостоятельно выполняет только небольшое число подаваемых ему команд; это, как правило, команды, связанные с изменением свойств самого интерпретатора: его настройка, смена текущего каталога, элементы программирования и т. п. Подавляющее большинство команд - это имена утилит, т. е. специально для этого написанных программ. Если команда не опознана как внутренняя команда shell, она интерпретируется как имя утилиты. Система эту утилиту запускает и передает ей все параметры из командной строки.
Все, что команда считает нужным сообщить пользователю о своей работе, передается в текстовом виде на тот же терминал. Всю переданную командой информацию принято называть ее выдачей. Выдача одной утилиты ничем, кроме смысла, не отличается от выдачи другой утилиты или от сообщения системы: текст как текст. Конечно, если пользователь опасается запутаться, у него всегда есть возможность отделить разные выдачи друг от друга.

Договоренности о формате командной строки

Можно различить два вида параметров: те, что изменяют поведение команды, и те, что передают команде дополнительную информацию (классическое разделение на поток управления и поток данных). Первый вид называется ключами (options), а второй - собственно параметрами. Параметры могут выглядеть как угодно (имена файлов, фамилии сотрудников, регулярные выражения, вообще любой текст), а ключи обычно имеют строго определенный вид.
Существует две договоренности по формату ключей. Первая - так называемый UNIX style, или односимвольный формат. Чтобы отличаться от параметра, ключ должен начинаться с символа "-". Второй символ - собственно ключ, он указывает, как именно видоизменяется работа команды. Например, утилита ls показывает список файлов в текущем каталоге. Команда ls имя-каталога воспринимает второй аргумент как параметр и показывает список файлов, находящихся в каталоге имя-каталога. Команды ls -l или ls -l имя-каталога покажут соответствующие списки в "длинном" (long) формате: вдобавок к именам файлов будет выведено немало дополнительной информации. Очень неплохо, если при именовании ключа соблюдается принцип аббревиативности: имя ключа - буква, с которой начинается имя производимого им действия.
Если так случилось, что параметр начинается с символа (например, параметр - отрицательное число), то существует специальный ключ "--" ("-" - это имя ключа, перед которым, по договоренности, должен стоять признак ключа, т. е. еще один "-"), который означает, что все последующие аргументы, как бы они ни выглядели, будут параметрами, а не ключами. Например, утилита cat занимается выводом на стандартное устройство вывода (терминал) всего того, что считала со стандартного устройства ввода. (Если вы запустили cat без параметров, нажмите клавишу Ctrl и одновременно D). В виде "cat имя-файла" cat выводит содержимое файла имя-файла. Поэтому для вывода на терминал содержимого файла -minus-first нужно ввести что-то вроде cat -- -minus-first.
Вторая договоренность по формату ключей носит название GNU style (или полнословный формат), так как зародилась она в недрах сообщества GNU, занимающегося свободным программным обеспечением. Причина появления этой более новой договоренности проста. Если команда имеет слишком широкие возможности, у нее появляется слишком много ключей. Запомнить или хотя бы отыскать в документации однобуквенный ключ (скорее всего, уже не аббревиативный, потому что букв на всех не хватает) непросто. Налицо явное нарушение У. Отчасти компенсировать это нарушение можно, если не слишком жестко придерживаться З и разрешить команде использовать ключи, имена которых говорят сами за себя. Полнословный ключ начинается с двух минусов и далее содержит одно (или чуть больше) слов-описателей, разделенных также знаком "-". Например, ключ -A (All) предписывает утилите ls вывести имена всех, в том числе "скрытых" файлов (файл, чье имя начинается на . считается скрытым; именно такие имена бывают у файлов и каталогов, создаваемых утилитами UNIX автоматически для своих нужд), кроме ".." и ".", имеющих специальный смысл. В нотации GNU этот ключ выглядит как --almost-all. Гораздо понятнее, но в шесть раз длиннее.
Часто используются так называемые параметрические ключи, т. е. ключи, которым самим требуются параметры. Например, в очень многих утилитах ключ -o означает перенаправление вывода в файл, поэтому следующий за ним параметр должен быть именем этого выходного файла. Скажем, утилита постраничного просмотра файлов less может записывать протокол работы пользователя в файл. Для этого ее надо вызвать с параметрами less что-смотрим -o протокол или, в нотации GNU, less что-смотрим --log-file=протокол. Обратите внимание на символ =, именно так в полнословном формате указывается параметр ключа.


Файловая система
Вернемся теперь к понятию "удобство". Для управления машиной человеку необходимо все время придумывать и набирать на клавиатуре некоторые команды, а затем анализировать результат - текстовое сообщение утилиты или самой системы. Как сделать этот диалог более эффективным?
Первая мысль: надо заставить машину делать за человека все, что ему делать лень, а именно - все, что можно сделать автоматически.
Все файлы системы, сотни тысяч и даже миллионы файлов размещаются на одном или нескольких файловых носителях (обычно на жестких дисках). У каждого файла есть собственное имя: так проще ими манипулировать. Если бы все файлы были свалены в одну кучу, легче бы все равно не стало; очевидно, что таких куч должно быть несколько. Куче, в которой могут храниться файлы, соответствует понятие каталог. На самом деле каталог - это специального вида файл, содержащий указатели на хранящиеся в нем файлы и подкаталоги.
Существует корневой каталог (в UNIX он называется просто /), в котором лежат все остальные доступные системе файловые ресурсы. В корневом каталоге могут храниться файлы (скорее всего - системные) и подкаталоги. В подкаталогах тоже могут лежать файлы и подкаталоги, и так все глубже до потери осмысленности (современные файловые системы не устанавливают максимальной глубины вложенности каталогов). Если требуется дать точный адрес какого-нибудь файла в этой файловой системе, описывается так называемое полное имя файла (или полный путь, absolute pathname): цепочка имен вложенных каталогов (в UNIX они разделяются символом "/"), которая начинается с "/" - "от корня" - и завершается именем файла (например, /usr/bin/vi). Получившаяся древовидная структура настолько привычна, что трудно представить себе какую-то иную организацию хранилища данных. А ведь когда-то она была, и уже довольно давно существуют новые разработки, в которых поиск файла происходит на основе не одного только пути, а целого набора атрибутов, как в базах данных.
В файловой системе UNIX можно хранить не только файлы и каталоги, но и объекты других типов; мы же вместо корректного словосочетания "имя ресурса файловой системы" будем употреблять компактное "имя файла", разумея под этим имя не только файла, но и всего, что при помощи файловой системы может быть поименовано.
Работа с файлами
Однако указывать всякий раз в командной строке полное имя файла неудобно. Чаще всего пользователь работает с файлами, находящимися в одном и том же каталоге: например, компилирует программу и редактирует тексты. В результате полный путь до этих файлов всегда будет одинаков вплоть до последнего "/". Понятие относительного пути (relative pathname) устраняет это неудобство: в каждый момент времени некоторый каталог файловой системы считается для командного интерпретатора текущим (или рабочим, work directory). И если имя файла или каталога начинается не с "/", оно считается не от корня, а от текущего каталога.
В нашем примере диалога пользователя и машины команды пользователя помечены $ в начале строки, остальное - выдача системы. Строчка "$" - так называемое "приглашение" командного интерпретатора, оно означает, что пользователь может подавать команду.
$ cd /usr/share/man/man1
$ pwd
/usr/share/man/man1
$ ls -l /usr/share/man/man1/ls.1.gz
-r--r--r-- 1 root wheel 6025 5 июн 05:54 /usr/share/man/man1/ls.1.gz
$ ls -l ls.1.gz
-r--r--r-- 1 root wheel 6025 5 июн 05:54 ls.1.gz
$ ls -l ./ls.1.gz
-r--r--r-- 1 root wheel 6025 5 июн 05:54 ./ls.1.gz
$ ls -l ../man1/ls.1.gz
-r--r--r-- 1 root wheel 6025 5 июн 05:54 ../man1/ls.1.gz
В UNIX команда pwd (print work directory) выдает имя текущего каталога, а команда cd позволяет его сменить. Если в командной строке необходимо указать имя текущего каталога, используется символ "."; строка ".." обозначает родительский каталог (тот, в который вложен текущий).
Для хранения собственных файлов пользователю, скорее всего, будет выделен специальный каталог. Этот каталог называется домашним каталогом пользователя, и именно он будет текущим для пользовательского shell`а непосредственно после входа в систему.
Генерация имен файлов
Допустим, в домашнем каталоге пользователя накопилось изрядное количество программ, написанных на языке Си, так что команда ls выдает два экрана имен файлов. И вот пользователь (наконец-то) придумал создать подкаталог src в своем домашнем каталоге, куда можно перенести все файлы, имена которых оканчиваются на ".c" (это и есть программы на Си). Хотелось бы выполнить перенос одной короткой командой, поскольку информации для работы системе достаточно. В самом деле,
$ mv *.c src
решает задачу (команда mv - move - занимается переименованием, а когда простого переименования недостаточно - делает копию файла, а затем удаляет его). Более того, если надо удалить все накопившиеся в результате компиляций объектные файлы (они заканчиваются на ".o"), можно написать
$ rm *.o
(команда rm - remove - занимается как раз удалением).
В обоих случаях мы использовали так называемый шаблон - специального вида строку, описывающую целый класс строк. Наличие в шаблоне символов '*' означает, что в подходящих строках в этом месте может стоять произвольное количество любых символов (даже ни одного). Например, шаблон 'a*b*c' подходит ко всем строкам, которые начинаются на 'a', заканчиваются на 'c' и имеют внутри 'b'. Под такой шаблон попадают, скажем, строки 'abc', 'aCcbaAc', 'a-%-bc' и 'aSd8bW5c' и не попадают '-abc' (не начинается на 'a'), 'a-B-c' (нет символа 'b', шаблоны чувствительны к регистру букв) и 'aDDDcb' (не кончается на 'c'). Здесь *.c и *.o описывают имена файлов, которые заканчиваются на .c и .o соответственно. Кроме '*' специальное значение в шаблоне имеет символ '?' (один любой символ) и '['. Пара скобок '[' и ']' определяет множество символов, из которых на данное место годится любой. Множество можно задавать перечислением самих символов, а можно - диапазоном, в котором указываются только первый и последний, а между ними ставится '-'. Например, запись '[i-ntx-z]' означает один символ из набора ijklmntxyz (для того, чтобы узнать больше про шаблоны, следует набрать man sh и открыть раздел Shell Patterns).
Когда шаблоны применяются в командной строке, shell проверяет, нет ли в системе файлов с попадающим под шаблон именем. Поскольку символ "/" (и только он) не может встречаться в имени файла, шаблон вообще без "/" относится к файлам текущего каталога, а шаблон, содержащий "/", к файлам, путь до которых соответствует шаблону. Например, команда
$ echo /usr/share/man/man*/*passwd*
выдаст как минимум два имени: /usr/share/man/man1/passwd.1.gz и /usr/share/man/man5/passwd.5.gz (команда echo просто выдает на терминал все переданные ей параметры).
Обратим внимание на то, что превращением шаблона в список файлов занимается именно shell, а не команда echo или утилиты вроде rm и ls. Заставлять каждую утилиту, работающую с файлами, разбирать шаблон самостоятельно - значит увеличить вероятность ошибки при написании процедуры разбора во столько раз, сколько утилит будут ею пользоваться. Лишняя работа! Поэтому, скажем, команда копирования файлов cp (copy) знать не знает ни о каких шаблонах, а воспринимает только ключи и имена файлов. Эта способность командного интерпретатора называется генерацией имен файлов.
У обработки шаблонов при помощи генерации имен есть два недостатка. Первый - утилита не имеет сведений о том, был ли использован шаблон. Сделать так, чтобы команда rm * перед удалением просила у пользователя подтверждения, можно только при помощи особых свойств командного интерпретатора. Но, с одной стороны, такая забота - уже нарушение О (подал команду - значит уже подумал и решил); а с другой стороны - есть ключ -i (interactive): rm -i * будет запрашивать подтверждение перед тем, как удалить каждый файл.
Закавычивание и экранирование
Второй недостаток серьезнее, но его гораздо проще обойти. Что если программа все-таки хочет сама обработать строку, содержащую спецсимволы? Надо бы уметь передавать символы *, ? и прочие в неизменном виде, иными словами, отключать генерацию имен. В shell такой механизм есть, он называется закавычиванием (или квотированием, quoting). Если вы заключаете строку в кавычки или апострофы, командный интерпретатор будет считать эту строку единым словом и не станет разбирать шаблоны внутри нее. Для того чтобы закавычить один символ, можно поставить перед ним обратную косую черту "\" (backslash) (этот символ повсеместно используется в UNIX для закавычивания). Таким образом, строки "a?"b, a'?b' и a\?b shell превращает в "a?b". Для того чтобы передать команде символ квотирования как неспециальный, квотируйте его другим:
$ echo "'", \", '"' и \\
', ", " и \
Иногда бывает необходимо ввести непечатный символ как обычный текстовый. Большинство непечатных символов можно подать с клавиатуры, нажав одновременно Ctrl и какую-нибудь букву (в документации принято писать ^буква, например, Ctrl+A превращается в ^A). Если такой символ к тому же немедленно выполняется командным интерпретатором или системой (например, ^U, ^C, Esc и т. п.), используйте экранирование - этакое закавычивание здесь и сейчас. Экранирование похоже на использование "\" - с той разницей, что экранирующий символ (обычно ^V) вообще не попадает на стандартный ввод, зато экранируемый - что бы он ни означал - передается как обычный.

Редактирование командной строки и истории

Что еще можно счесть удобством при работе в командной строке? Редактирование самой строки. Вообще-то терминальная линия UNIX поддерживает минимальный набор операций с вводимой строкой: удаление последнего введенного символа (обычно ^H - клавиша Backspace или ^? - клавиша Delete), удаление слова (^W) и удаление всей строки (^U). Однако, когда помногу работаешь в командной строке, начинаешь понимать, что этого недостаточно. Хочется, чтобы работали стрелочки вправо и влево (и прочие перемещения курсора внутри строки: на начало, на конец, по словам). Желательно также, чтобы Backspace удалял символ перед курсором, а Delete - после. Здесь появляется одна неприятная задачка, о решении которой в развернутом виде будет сказано в лекциях 8 и 15. Пока только обозначим ее: терминальное устройство (в IBM PC) вообще не обязано иметь стрелочек на клавиатуре. А если стрелочки есть, неизвестно, какие именно символы (ничего другого нельзя передать по терминальной линии) будет посылать в компьютер нажатие этих стрелочек. Точно так же дела обстоят со всеми небуквенными клавишами, включая Delete, Home, Page Down или F9. Что делать?
Первый вариант - не использовать их, задействовать управляющие последовательности вида ^B (backward), ^F (forward), ^A (начало строки), ^E (конец строки) и т. п. При этом, чтобы не множить сущности, надо сделать их такими же, как в текстовом редакторе, построенном по той же схеме взаимодействия с клавиатурой. Обычно эти команды совпадают с аналогичными в emacs (или info). Или же ввести двухрежимный способ работы, как в редакторе ed или (что несколько сложнее) vi (см. главу 15), и пользоваться обычными символами как командами.
Второй подход - попробовать заданные emacs-style клавиатурные команды прикреплять к имеющимся на данном терминале клавишам. Для этого нужно заранее знать, какие именно символы посылает та или иная клавиша терминала, т. е. иметь некоторую базу данных терминалов и научить shell к ней обращаться. Такое прикрепление носит название binding и возможно только в современных версиях командных интерпретаторов.
Мы не упомянули о стрелочках вверх и вниз (и о соответствующих им emacs-style командах ^P, previous, и ^N, next) оттого, что они нужны уже не для простого редактирования, а для работы с историей команд. Часто бывает нужно вызвать предыдущую команду и отредактировать ее - например, чтобы исправить допущенную ошибку. Значит, предыдущую (а раз так, то и последнюю пару сотен) команду надо бы запоминать, записывать в файл, уметь вспоминать и т. д. Почти во всех shell есть команда !! - повторение предыдущей и !номер - повторение команды номер из файла истории. Однако пользоваться стрелочками для просмотра того файла привычнее и нагляднее, для чего ^P и ^N прикрепляют к "стрелке вверх" и "стрелке вниз".
Весьма удобно, если по файлу истории можно искать подстроку (например, чтобы восстановить точный синтаксис команды, про которую мы помним только, что она работала с файлом zoom.wing.txt). Многие командные интерпретаторы позволяют просто нажать ^R, вписать zoom.wing.txt (или даже более короткую строку) и параллельно показывать подходящие записи из файла истории; а когда запись найдется, можно просто нажать Enter.

Сокращения

Если вы замечаете, что часто используете довольно длинную составную команду (например, ls -FACs или, в случае GNU ls, ls --classify --almost-all --color=auto (команда man ls пояснит, что все это значит), может возникнуть желание ее укоротить. Как будет показано в лекции 11, можно написать короткую программу-сценарий на shell, назвать ее, скажем, l и запускать вместо полной строки. У этого метода есть три мелких недостатка, которые в сумме мешают пользователю поступать именно так. Во-первых, надо уметь обращаться с текстовым редактором быстро, иначе проще будет каждый раз набирать длинную строчку, чем заставить себя вписать ее в сценарий и затем использовать короткую. Во-вторых, для того, чтобы запускаемая команда выглядела как l, а не как /bin/sh /home/user/bin/l, надо выполнить ряд дополнительных действий, о которых следует знать (мы расскажем о них в лекции 10). В-третьих, для выполнения такой команды всякий раз будет запускаться отдельная копия командного интерпретатора.
Это само по себе при современных скоростях заметной нагрузки системе не прибавит (было 10 милисекунд, стало 100). Однако, если такую удобную команду использовать часто, различие между простым запуском утилиты и загрузкой shell, который в свою очередь запускает утилиту, может стать ощутимым: умножьте, например, числа в предыдущем примечании на 100. Первые два недостатка после трех месяцев работы в UNIX становятся несущественными.
Но зачем усложнять? Практически любой командный интерпретатор умеет запоминать сокращения (aliases) - заданные пользователем последовательности символов, которые будут заменяться на другие после того, как командная строка введена. Например, во многих случаях достаточно написать alias l="ls -FACs", после чего командный интерпретатор будет заменять l на ls -FACs, если l стоит в позиции имени команды (чаще всего - первое слово командной строки).

Достраивание

Использование шаблонов - удобный способ коротко информировать командный интерпретатор о многом. Однако он немного дает пользователю в информативном плане, скорее даже слегка усложняет. Заметив как-то, что во время работы частенько приходится повторять команды вида

$ ls prog*c
prog1.c program.cc  prographic  progr.c
$ vi progr.c

разработчики командного интерпретатора решили исключить из них "обезьянью" часть - переписывание имени файла с экрана. Пусть shell работает! Если мы, допустим, уже набрали часть команды vi_prog (утилита vi - мощный текстовый редактор, в лекции 15 рассказано, как с ним обращаться), то пускай теперь система покажет нам все возможные варианты продолжения этой команды (в данном случае - подходящие имена файлов в текущем каталоге). Подаем интерпретатору специальную команду (обычно это клавиша Tab или ^D), и, в зависимости от настроек, нам будет предложено выбрать один из файлов или просто подставится первое из подходящих имен (при этом повторное нажатие Tab покажет второе имя, и так по кругу). Такое свойство современных командных интерпретаторов называется достраиванием имен файлов (filename completion). Это слегка расхолаживает пользователя, но позволяет экономить время на вводе команд.
Тактика достраивания может быть распространена на бесчисленное множество случаев: например, если мы написали cd_d и просим shell достроить d до имени существующего файла, имеет смысл показывать подходящие имена одних только каталогов. Дальше - больше. Многие утилиты пользуются стандартным соглашением о формате команд и, в частности, поддерживают ключ -h или --help для вывода короткой подсказки. Можно попросить shell (если, конечно, это будет довольно "умный" shell, см. "Сравнительную таблицу командных интерпретаторов"), чтобы на ввод command "--" и Tab он тайком запускал command --help и показывал результат в качестве подсказки, а не то сам разбирал этот результат и подставлял по очереди все ключи вида

--имя_ключа! 
 
На главную | Содержание | < Назад....Вперёд >
С вопросами и предложениями можно обращаться по nicivas@bk.ru. 2013 г.Яндекс.Метрика