Обратные апострофы в списочном контексте

Если результат выполнения команды состоит из нескольких строк, в скалярном контексте обратные апострофы возвращают одну длинную строку с внутренними символами новой строки. Однако при использовании той же строки в списочном контексте создается список, один элемент которого соответствует одной строке вывода. Например, команда UNIX who обычно выдает строку текста для каждого текущего пользователя в системе:

merlyn tty/42 Dec 7 19:41
rootbeer console Dec 2 14:15
rootbeer tty/12 Dec 6 23:00

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

my $who_text = `who`;

Но в списочном контексте данные сразу возвращаются с разбивкой по строкам:

my @who_lines = `who`;

@who_lines содержит элементы, каждый из которых завершается символом новой строки. Конечно, можно удалить все эти символы функцией chomp, но давайте пойдем в другом направлении.


Если разместить вызов в обратных апострофах в заголовке foreach, цикл автоматически переберет все строки, последовательно присваивая каждую из них переменной $_:

foreach (`who`) {
my($user, $tty, $date) = /(\S+)\s+(\S+)\s+(.*)/;
$ttys{$user} .= "$tty at $date\n";
}

Для приведенных выше данных цикл выполняется три раза. (Вероятно, в вашей системе количество активных входов будет больше трех.) Обратите внимание на поиск по регулярному выражению; в отсутствие оператора привязки (=~) он применяется к переменной $_, и это хорошо, потому что именно в этой переменной хранятся выходные данные команды. Регулярное выражение ищет шаблон вида «непустое слово, пропуски, непустое слово, пропуски, а затем весь остаток строки до символа новой строки, но не включая его (так как точка по умолчанию не совпадает с символом новой строки)». Таким образом, при первой итерации в $1 сохраняется строка "merlyn", в $2 – строка "tty/42", а в $3 – строка "Dec 7 19:41". Однако регулярное выражение применяется в списочном контексте, поэтому вместо логического значения «совпало или нет» мы получим список заполненных переменных. Переменная $user заполняется строкой "merlyn" и т. д. Вторая команда в этом цикле просто сохраняет tty и дату, присоединяя их к текущему значению в хеше (возможно, undef), потому что пользователь может присутствовать в списке несколько раз (как пользователь "rootbeer" в нашем примере).

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

Статьи из раздела Perl на эту тему:
Ветвление
Выполнение команд в обход командного процессора
Обратные апострофы и сохранение вывода
Отправка и прием сигналов
Переменные среды

Вернуться в раздел: Perl / 15. Управление процессами