Анимация
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

Глава 13 Манипулирование файлами и каталогами "

1. Вот один из способов решения этой задачи:

unlink @ARGV;

Да, именно так. Массив @argv - это список имен, подлежащих удалению. Операция unlink получает список имен, поэтому нам нужно лишь соединить два этих компонента, и дело сделано.

Конечно, здесь не реализован ни механизм уведомления об ошибках, ни опции - f и -1, ни другие подобные вещи, но это было бы уже слишком серьезно. Если вы это сделали - отлично!

2. Вот один из способов решения этой задачи:

($old, $new) = gARGV; # назвать их

if (-d Snew) { # новое имя - каталог, его нужно откорректировать

($basename = $old) =~ s#.*/##s; # получить название собствеино

# каталога $old

$new .= "/$basename"; # и добавить его к новому имени

rename($old,$new) I die "Cannot rename $old to $new: S";

Рабочая лошадка в этой программе - последняя строка, но все остальное тоже нужно на тот случай, если новое имя принадлежит каталогу.

Сначала мы даем наглядные имена двум элементам массива SARGV. Затем, если имя $new - каталог, нам нужно откорректировать его, добавив в конец нового имени собственно имя каталога $old. Это значит, что переименование /usr/src/fred в /etc фактически приводит к переименованию /usr/src/fred в /etc/fred.

Наконец, после добавления собственно имени каталога мы завершаем задачу вызовом rename.

3. Вот один из способов решения этой задачи:

($old, $new) = @ARGV; # назвать их

if (-d $new) { # новое имя - каталог, его нужно откорректировать

($basename = $old) =~ s#.*/##s; # получить название собственно

# каталога $old

$new .= "/$basename"; # и добавить его к новому имени

link($old,$new) I I die "Cannot link $old to $new: $";

Эта программа идентична предыдущей программе за исключением самой последней строки, потому что мы создаем ссылку, а не выполняем переименование.



4. Вот один из способов решения этой задачи:

if ($ARGV[0] eq "-s") ( # нужна символическая ссылка 5symlink++; # запомнить shift(@ARGV); # и отбросить флаг -s

($old, $new) = @ARGV; # назвать их

if (-d $new) ( # новое имя - каталог, его нужно откорректировать

($basename = $old) =~ s#.*/##s; # получить название собственно

# каталога $old $new .= "/$basename"; # и добавить его к новому имени

if ($symlink) { # wants а symlink

symlink($old,$new); ] else ( # нужна жесткая ссылка

link($old,$new);

Средняя часть этой программы - такая же, как в предыдущих двух упражнениях. Новые здесь - несколько первых и несколько последних строк.

В первых строках осуществляется проверка первого аргумента программы. Если этот аргумент равен -s, то скалярная переменная $symlink инкрементируется, получая в результате значение 1. Затем выполняется сдвиг массива @argv, в результате чего удаляется флаг -s. Если флаг -s отсутствует, то ничего не делается и $symlink остается равной undef. Сдвиг массива @argv выполняется достаточно часто, поэтому имя массива @argv является аргументом функции shift по умолчанию; то есть вместо

shift(@ARGV);

МЫ могли бы написать

shift;

Последние несколько строк проверяют значение $ symlink. Оно будет равно либо 1, либо undef, и на основании этого для файлов выполняется либо операция symlmk, либо link.

5. Вот один из способов решения этой задачи:

foreach $f (<*>) {

print "$f -> $where\n" if defined($where = readlink($f));

Скалярной переменной $f присваивается по очереди каждое из имен файлов текущего каталога. Для каждого имени переменной $ where присваивается значение, полученное в результате выполнения функции readlink () ДЛЯ данного имени. Если имя - не символическая ссылка, то операция readlink возвращает undef, давая значение "ложь" в



проверке if, а print пропускается. Если же операция readlink возвращает какое-то значение, то print выводит название символической ссьшки и имя файла или директории, на которую она указывает.

Глава 14 Управление процессами

1 Вот один из способов рещения этой задачи:

if ( date =~ /"S/) {

print "Go play\n"; 1 else (

print "Get to work\n";

Оказывается, команда date выводит букву s в качестве первого символа только по выходным (Sat или Sun), что делает задачу тривиальной. Мы вызываем date, затем с помощью регулярного выражения смотрим, является ли первый символ буквой S. На основании результата мы выводим одно сообщение или другое.

2 Вот один из способов рещения этой задачи:

open(PW,"/etc/passwd"); while (<PW>) ( chomp,

($user,$gcos) = (split /:/)[0,4]; ($real) = split(/,/, $gcos); $reaH$user) = $real;

close(PW),

open(WHO,"who I") die "cannot open who pipe"; while (<WH0>) (

($login, $rest) = /-(\S+) \s+(. *)/;

Slogin = $reaH$login) if $reaH $login);

printf "%-30s %s\n",$login, $rest,

В первом цикле создается хещ %real, ключи которого - регистрационные имена, а значения - соответствующие реальные имена. Этот хещ используется в следующем цикле для замены регистрационного имени на реальное.

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



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