Компания ALT Linux
Опубликован: 14.12.2004 | Доступ: свободный | Студентов: 12068 / 1395 | Оценка: 4.19 / 3.84 | Длительность: 18:18:00
ISBN: 978-5-9556-0019-1
Лекция 7:

Интерфейс

< Лекция 6 || Лекция 7: 1234 || Лекция 8 >

Файловая система

Вернемся теперь к понятию " удобство ". Для управления машиной человеку необходимо все время придумывать и набирать на клавиатуре некоторые команды, а затем анализировать результат - текстовое сообщение утилиты или самой системы. Как сделать этот диалог более эффективным?

Первая мысль: надо заставить машину делать за человека все, что ему делать лень, а именно - все, что можно сделать автоматически.

Все файлы системы, сотни тысяч и даже миллионы файлов размещаются на одном или нескольких файловых носителях (обычно на жестких дисках). У каждого файла есть собственное имя: так проще ими манипулировать. Если бы все файлы были свалены в одну кучу, легче бы все равно не стало; очевидно, что таких куч должно быть несколько. Куче, в которой могут храниться файлы, соответствует понятие каталог. На самом деле каталог - это специального вида файл, содержащий указатели на хранящиеся в нем файлы и подкаталоги.

Существует корневой каталог (в UNIX он называется просто / ), в котором лежат все остальные доступные системе файловые ресурсы. В корневом каталоге могут храниться файлы (скорее всего - системные) и подкаталоги. В подкаталогах тоже могут лежать файлы и подкаталоги, и так все глубже до потери осмысленности (современные файловые системы не устанавливают максимальной глубины вложенности каталогов ). Если требуется дать точный адрес какого-нибудь файла в этой файловой системе, описывается так называемое полное имя файла (или полный путь, absolute pathname): цепочка имен вложенных каталогов (в UNIX они разделяются символом " / "), которая начинается с " / " - "от корня" - и завершается именем файла (например, /usr/bin/vi ). Получившаяся древовидная структура настолько привычна, что трудно представить себе какую-то иную организацию хранилища данных. А ведь когда-то она была (см., например, [ 43 ] ), и уже довольно давно существуют новые разработки, в которых поиск файла происходит на основе не одного только пути, а целого набора атрибутов, как в базах данных [ 17 ] .

В файловой системе 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 ) вообще не попадает на стандартный ввод, зато экранируемый - что бы он ни означал - передается как обычный.

< Лекция 6 || Лекция 7: 1234 || Лекция 8 >
Andranik Avakian
Andranik Avakian

41. УК РФ и Комментарии (ст. 273)

М. 2000 г. Издательство: ALT Linux, Институт Логики

Уголовный Кодекс РФ и комментарии к нему?

По ссылке открывается сайт документации Linux, раздел Linux Installation and Getting Started

Сергей Петровский
Сергей Петровский

У Вас написано:

ls -dt1 `grep -il отчет *` | head -1

если знания по шелу мне не изменяют, то должно быть:

ls -dt | `grep -il отчет *` | head -1

Максим Молокотин
Максим Молокотин
Россия, Удмуртская республика
Александр Иконников
Александр Иконников
Россия, Ижевск