Создание и удаление каталогов

Создать новый каталог в существующем каталоге несложно. Просто вызовите функцию mkdir:

mkdir "fred", 0755 or warn "Cannot make fred directory: $!";

И снова при успешном создании возвращается true, а при неудаче задается переменная $!. Но что означает второй параметр, 0755? Он определяет начальные разрешения1 для созданного каталога (разрешения всегда можно изменить позднее). Значение задается в восьмеричном формате, потому что оно будет интерпретироваться в стандартном формате UNIX с группами из 3 бит, а восьмеричные значения удобны для представления такой группировки. Да, даже в Windows и MacPerl для использования функции mkdir необходимо кое-что знать о разрешениях UNIX. Режим 0755 предоставляет вам полный набор разрешений, а всем остальным пользователям – доступ только для чтения (без возможности что-либо изменить).

Функция mkdir не требует, чтобы значение задавалось в восьмеричном формате – она просто берет передаваемое число (литерал или результат вычисления). Но если вы не сможете быстро прикинуть, что восьмеричное число 0755 соответствует десятичному 493, вычисления лучше поручить Perl. А если нечаянно опустить начальный нуль, вы получите десятичное число 755, то есть 1363 в восьмеричной записи – довольно странная комбинация разрешений.


Как было показано в главе 2, строковое значение, используемое как число, никогда не интерпретируется в восьмеричной системе счисления, даже если оно начинается с 0. Следовательно, такая запись работать не будет:

my $name = "fred";
my $permissions = "0755"; # Не получится
mkdir $name, $permissions;

Кажется, мы только что создали каталог со странными разрешениями 01363 из-за того, что число 0755 было случайно интерпретировано как десятичное. Чтобы избежать подобных неприятностей, используйте функцию oct, которая обеспечивает восьмеричную интерпретацию строки независимо от присутствия начального нуля:

mkdir $name, oct($permissions);

Конечно, если значение задается прямо в программе, используйте число вместо строки. Необходимость в дополнительной функции oct чаще всего возникает при получении данных от пользователя. Предположим, аргументы передаются в командной строке:

my ($name, $perm) = @ARGV; # Первые два аргумента - имя и разрешения
mkdir $name, oct($perm) or die "cannot create $name: $!";

Значение $perm изначально задается как строка, поэтому функция oct обеспечивает правильную восьмеричную интерпретацию.


Пустые каталоги удаляются функцией rmdir. Функция отчасти напоминает unlink, но может удалять только один каталог при каждом вызове:

foreach my $dir (qw(fred barney betty)) {
rmdir $dir or warn "cannot rmdir $dir: $!\n";
}

Если каталог не пуст, попытка вызова rmdir завершается неудачей. Сначала следует попытаться удалить содержимое каталога функцией unlink, а затем попробуйте удалить каталог, который к этому моменту должен быть пуст. Предположим, нам необходимо место для записи временных файлов в ходе выполнения программы:

my $temp_dir = "/tmp/scratch_$$"; # Определяется по идентификатору
# процесса; см. в тексте
mkdir $temp_dir, 0700 or die "cannot create $temp_dir: $!";
...
# Каталог $temp_dir используется для хранения всех временных файлов
...
unlink glob "$temp_dir/* $temp_dir/.*"; # Удалить содержимое $temp_dir
rmdir $temp_dir; # Удалить пустой каталог

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


(На практике наряду с идентификатором процесса часто используется имя программы; если программа называется quarry, каталог принимает вид /tmp/quarry_$$.) При завершении работы программы последний вызов unlink должен удалить все файлы из временного каталога, после чего функция rmdir удалит пустой каталог. Но если в каталоге были созданы подкаталоги, для них вызов unlink завершится неудачей, и общий вызов rmdir тоже не сработает. Если вам потребуется более надежное решение, поинтересуйтесь функцией rmtree из модуля File::Path из стандартной поставки Perl.

Оцените статью: (0 голосов)
0 5 0

Статьи из раздела Perl на эту тему:
Альтернативный синтаксис глобов
Глобы
Дескрипторы каталогов
Изменение временных меток
Изменение разрешений

Вернуться в раздел: Perl / 12. Операции с каталогами