Операция ввода команды
Ни одна программа не может функционировать сама по себе, не получая и не посылая информацию во внешнюю среду. Perl предоставляет несколько способов получения программой данных извне и вывода информации из выполняющегося сценария. В процессе функционирования программы может потребоваться выполнить некоторую команду операционной системы и проанализировать результаты ее выполнения, прочитать данные из внешнего файла или группы файлов, записать результаты вычислений во внешний файл или отобразить их на экране монитора — все эти действия реализуются разнообразными операциями и функциями языка Perl.
Простейшее взаимодействие с операционной системой, в которой выполняется программа Perl, реализуется операцией заключения строки данных в обратные кавычки. Содержимое такой строки передается на выполнение операционной системы, которая возвращает результат выполнения команды в эту же строку.
Для чтения из файла используется операция "ромб" о, которой в качестве операнда передается дескриптор файла. В этой главе мы не будем обсуждать ввод из файла через его дескриптор, отнеся рассмотрение этого вопроса в следующую главу, полностью посвященную работе с файлами. Здесь мы расскажем о том, как работает операция "ромб" в случае отсутствия операнда, представляющего дескриптор файла. В этом случае эта операция может читать записи из стандартного файла ввода STDIN или получать информацию, передаваемую программе через командную строку.
Для отображения в стандартный файл вывода STDOUT используется уже знакомая нам функция print, которая, однако, может выводить информацию и в файл, определенный своим дескриптором.
Заключенная в обратные кавычки "•"• строка символов является всего лишь удобной формой записи операции ввода команды операционной системы qx{}, с которой мы уже знакомы (см. часть 4).
Когда интерпретатор Perl встречает строковый литерал в обратных кавычках, он осуществляет подстановку в нее значений скалярных переменных и переменных массивов и передает получившуюся строку, как команду, на выполнение операционной системе. Последняя выполняет ее и возвращает в строковый литерал результаты вывода команды на стандартное устройство вывода, которым обычно является экран монитора. В связи с таким "поведением" строкового литерала в обратных кавычках его иногда называют псевдолитералом.
Операция ввода команды различает скалярный и списковый контексты, в которых она может выполняться. В скалярном контексте возвращается одна строка, содержащая весь вывод на экран монитора выполненной команды, включая символы новой строки в случае многострочного вывода. В списковом контексте возвращается список значений, каждое из которых содержит одну строку вывода. Пример 6.1 демонстрирует использование операции ввода команды в соответствующих контекстах.
#! peri -w
$command = "dir";
$scalar = ~$command'; # Скалярный контекст. ,
@list = '$command~; # Списковый контекст.
print $scalar;
print $list[0], $list[lj;
При выполнении операции заключения в кавычки сначала осуществляется подстановка значения скалярной переменной $ command, а потом полученная строка передается на выполнение операционной системы. Переменная $scaiar (скалярный контекст) содержит весь вывод на экран монитора содержимого текущего каталога, поэтому при ее печати мы увидим все, что вывела команда dir. Когда результаты выполнения команды присваиваются массиву @iist (списковый контекст), то каждая строка вывода команды становится элементом массива, поэтому последний оператор печати примера 6.1 выводит первую и вторую строки.
В списковом контексте разбиение вывода команды операционной системы на элементы списка осуществляется в соответствии со значением встроенной переменной $/, которое используется в качестве разделителя. По умолчанию эта переменная содержит символ конца строки "\п" — поэтому и разбиение на элементы происходит по строкам. Присваивая этой переменной новое значение, мы тем самым определяем новое значение разделителя, которое будет использоваться при формировании элементов списка. Разделителем может быть любая последовательность символов. Например, в примере 6.2 в качестве разделителя задается строка "<КАТАЛОГ>".
§! peri -w
$/ = "<КАТАЛОГ>";
@list = ~dir s ; t Списковый контекст.
print $list[l], $list[2];
Теперь, в отличие от примера 6.1, элемент массива $iist[ 0j содержит не первую строку вывода команды dir, а вывод команды до первой встретившейся в нем последовательности символов "<КАТАЛОГ>". Аналогично, элемент $list[l] содержит вывод команды до следующей встретившейся последовательности СИМВОЛОВ "<КАТАЛОГ>" И Т. Д.
Команда, содержащаяся в псевдолитерале, выполняется всякий раз, как вычисляется этот псевдолитерал. Встроенная переменная $? содержит числовое значение состояния выполненной команды.
(Об интерпретации значений встроенной переменной $ ? см. часть 14 щелкни здесь.)
Хотим обратить внимание читателя еще раз на тот факт, что операция ввода команды возвращает вывод на стандартное устройство вывода операционной системы. При выполнении команды можно направить ее вывод на другое устройство, например, в файл. Для этого в строке после имени команды и всех необходимых для ее выполнения параметров следует задать символ ">", после которого ввести имя файла. В этом случае на экран монитора ничего выводиться не будет, а следовательно и ничего не будет возвращаться в псевдолитерал, т. е. после выполнения такой команды псевдолитерал будет содержать неопределенное значение (пример 6.3).
#! peri -w - $/ = "<КАТАЛОГ>";
$list = 'dir >file.dat~; # Вывод осуществляется в файл file.dat print $list; # Оператор ничего не напечатает!
Замечание
Обобщенная форма операции заключения в обратные кавычки qx {} работает точно так же, как и операция заключения в обратные кавычки " * '".