Анимация
JavaScript


Главная  Библионтека 

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 [ 53 ] 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103

Для каждого процесса* назначается свой текущий каталог. Когда запускается новый процесс, он наследует текущий каталог своего родительского процесса, но на этом вся связь заканчивается. Если Perl-программа меняет свой каталог, это не влияет на родительский shell (или иной объект), который запустил этот Perl-процесс. Точно так же процессы, создаваемые Perl-программой, не влияют на текущий каталог самой этой программы. Текущие каталоги для новых процессов наследуются от текущего каталога Perl-программы.

По умолчанию функция chdir без параметра делает текущим начальный каталог, почти так же, как команда cd shell.

Развертывание

Если в качестве аргумента в командной строке стоит звездочка (*), то shell (или тот интерпретатор командной строки, которым вы пользуетесь) интерпретирует ее как список имен всех файлов, находящихся в текущем каталоге. Так, если вы дали команду rm *, то она удалит все файлы из текущего каталога. (Не делайте этого, если не хотите потом долго приставать к системному администратору с просьбами о восстановлении файлов.) Еще примеры: аргумент [а-ш] * . с превращается в список имен файлов, находящихся в текущем каталоге, которые начинаются с одной из букв первой половины алфавита и заканчиваются на .с, а аргумент /etc/host* - в список имен файлов каталога/ete, которые начинаются со слова host. (Если для вас это ново, то перед дальнейщей работой рекомендуем почитать дополнительную литературу о сценариях shell.)

Преобразование аргументов вроде * или /etc/host* в список соответствующих имен файлов называется развертыванием (globbing). Perl обеспечивает развертывание с помощью очень простого механизма: подлежащий развертыванию образец заключается в угловые скобки или же используется функция glob.

@а = </etc/host*>

@а = glob("/de/host*");

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

while (defined(Snextname = </etc/host*>)) { print "one of the files is $nextname\n";

Это справедливо для UNfX и большинства других современных операционных систем.



Здесь возвращенные имена файлов начинаются с префикса, соответствующего пути доступа к ним {/etc/host), поэтому, если вам нужна только последняя часть имени, придется выделять ее самостоятельно, например:

while (Snextname = </etc/host*>) (

Snextname =~ s#.*/##; # удалить часть до последней косой черты print "one of the files is $nextname\n";

Внутри аргумента допускается указывать несколько образцов; эти списки развертываются отдельно, а затем конкатенируются так, как будто это один больщой список:

@fred barney flies = <fred* barney*>;

Другими словами, эта операция развертывания выдает те же значения, которые возвратила бы эквивалентная ей команда echo с такими же параметрами.*

Хотя развертывание списка файлов и сопоставление с регулярным выражением осуществляются почти одинаково, специальные символы имеют соверщенно разный смысл. Не путайте эти механизмы, иначе будете удивляться, почему вдруг < \ . с$> не находит все файлы, имена которых заканчиваются на .с!

В аргументе функции glob перед развертыванием производится интерполяция переменных. С помощью Perl-переменных можно выбирать файлы, задаваемые строкой, вычисляемой во время выполнения:

if (-d "/usr/etc") (

$where = "/usr/etc"; } else {

?where = "/etc";

Pfiles = <$where/*>;

Здесь переменной $where присваивается одно из двух имен каталогов в зависимости от того, существует каталог /usr/etc или нет. Затем мы получаем список файлов, находящихся в выбранном каталоге. Обратите внимание: переменная $where является развертываемой, т.е. подлежащими развертыванию символами являются /etc/* или /usr/etc/*.

Есть одно исключение из этого правила: образец <$var> (который означает использование в качестве развертываемого выражения переменной $var) должен записываться как <${var}>. В причины появления этого исключения сейчас лучще не вдаваться.**

* Для вас не будет сюрпризом узнать о том, что для выполнения развертывания Perl просто запускает C-shell, который раскрывает указанный список аргументов, и производит синтаксический анализ того, что получает обратно.

** Конструкция <Sfred> читает строку из дескриптора файла, заданного содержимым скалярной переменной $fred. Наряду с некоторыми другими особенностями, неупомянутыми в нашей книге, эта конструкция позволяет использовать косвенные дескрипторы файлов, где имя дескриптора передается и обрабатывается так, как будто это данные.



Дескрипторы каталогов

Если в вашей конкретной разновидности операционной системы имеется библиотечная функция readdir или ее функциональный эквивалент, Perl обеспечивает доступ к этой программе (и ее спутницам) с помощью дескрипторов каталогов. Дескриптор каталога - это имя из отдельного пространства имен, и предостережения и рекомендации, которые касаются дескрипторов файлов, касаются также и дескригггоров каталогов (нельзя использовать зарезервированные слова, рекомендуется использовать верхний регистр). Дескриптор файла fred и дескриптор каталога fred не связаны между собой.

Дескриптор каталога представляет собой соединение с конкретным каталогом. Вместо чтения данных (как из дескриптора файла) вы используете дескриптор каталога для чтения списка имен файлов в этом каталоге. Дескрипторы каталогов всегда открываются только для чтения; нельзя использовать дескриптор каталога для изменения имени файла или удаления файла.

Если функции readdirO и ее аналогов в библиотеке нет (и при инсталляции языка Perl никакую замену вы не предусмотрели), то использование любой из этих программ приведет к фатальной ошибке и ваша программа компиляцию не пройдет: она аварийно завершится до выполнения первой строки кода. Perl всегда старается изолировать вас от влияния рабочей среды, но такие чудеса ему не подвластны.

Открытие и закрытие дескриптора каталога

Функция opendir работает аналогично библиотечному вызову с тем же именем в С и С++. Ей дается имя нового дескриптора каталога и строковое значение, задающее имя открываемого каталога. Если каталог может быть открыт, opendir возвращает значение "истина"; в противном случае ог:а возвращает "ложь". Вот пример:

opendir(ETC,"/etc") die "Cannot opendir /etc: $!";

После этого обычно следуют разного рода манипуляции с дескриптором каталога etc, но сначала, наверное, нужно разобраться, как закрывать дескриптор каталога. Это делается с помощью функции closedir, которая весьма похожа на close:

closedir(ETC);

Как и close, closedir часто оказывается ненужной, потому что все дескрипторы каталогов автоматически закрываются перед повторным открытием либо в конце программы.

170 Ияучпе.ы PERL



0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 [ 53 ] 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103