#perl #bash
#perl #bash
Вопрос:
У меня есть bash-скрипт, который выдает разные целочисленные значения. Когда я запускаю этот скрипт, выходные данные выглядят следующим образом:
12
34
34
67
6
Этот скрипт выполняется на сервере Solaris. Чтобы предоставить другим пользователям в сети эти значения, я решил написать скрипт на Perl, который может:
- запускаем файл bash
- считываем его выходные данные
- создайте крошечную HTML-страницу с таблицей, в которой хранятся значения bash
Это тяжелая работа для меня, потому что у меня почти нет опыта работы с Perl. Я знаю, что могу использовать system для выполнения команд unix (и файлов bash), но я не могу получить выходные данные. Я также услышал о qx, который кажется очень полезным для моего случая.
Но я должен признать, что понятия не имею, как начать… Не могли бы вы дать мне несколько советов, как это решить?
Ответ №1:
С таким вопросом немного сложно понять, с чего начать.
qx
То, на что вы ссылаетесь, является особенностью Perl. «q *» или «Операторы, заключенные в кавычки и подобные им операторы» задокументированы на справочной странице Perl «operators» (обычно вы используете man perlop
для чтения в системах с обычной установкой Perl).
В частности, qx
это «выполнение команды в кавычках» … который по сути является альтернативной формой оператора ` (обратный тик или «замена команды») в Perl.
Другими словами, если вы выполните команду типа:
perl -e ‘$foo = qx{ls}; выводим «n###n $ foon####n»;’
… в системе с установленным Perl затем следует запустить Perl, который должен вычислить (-e) указанное вами выражение (в кавычках). Другими словами, мы пишем небольшую программу прямо в командной строке. Эта программа начинается с создания переменной, содержимое которой будет «скалярным» (что в терминологии Perl означает строку или число). Мы присваиваем (оператор = , или присваивание) выходные данные, которые записываются при выполнении ls
команды, обратно этой переменной ($foo). После этого мы печатаем содержимое нашей переменной (независимо от того, что ls
напечатала бы команда) со строками ###, предшествующими и следующими за этим содержимым..
Особенность qx
оператора Perl (и различных других операторов q *) заключается в том, что он позволяет вам разделять команду практически любыми символами, которые вам нравятся. Например, perl -e '$bar = qx/pwd/;'
было бы зафиксировать выходные данные pwd
команды. Когда вы используете любой из символов, которые обычно используются в качестве разделителей вокруг текстовых круглых скобок и т.д.), То qx
команда будет искать соответствующий разделитель. Если вы используете любую другую пунктуацию (или не буквенно-цифровой символ?) тогда этот же символ также будет завершающим разделителем. Это последующее поведение похоже на функцию команды «substitution» из старой sed
утилиты и ed
редакторов строк и было вдохновлено ею; в то время как сопоставление круглых скобок и т.д. Является новинкой Perl.
Итак, это основы того, как записывать выходные данные вашего скрипта оболочки. Чтобы напечатать числа в HTML-таблице, вам пришлось бы разделить полученные выходные данные на отдельные строки (сохранив их в виде списка или массива), затем распечатать свой HTML-пролог (теги <table>
и <th>
(заголовок) и так далее)… они перебирают серию <tr>
строк, интерполируя ваши числа в <td>>
контейнеры (табличные данные)) и затем, наконец, печатаем ваш HTML-эпилог (с закрывающими тегами).
Для этого вам нужно прочитать о print
функции Perl и о «интерполяции» в Perl. Это довольно сложная тема.
Все это чрезвычайно грубо, и существуют инструменты, которые позволяют вам подойти к генерации HTML на гораздо более высоком уровне. Также довольно сомнительно, что вы хотите обернуть выполнение вашего shell-скрипта в Perl-скрипт, поскольку представляется вероятным, что вы могли бы модифицировать shell-скрипт для прямого вывода HTML (возможно, как параметр, управляемый переключателем командной строки или переменной среды) или что вы могли бы переписать shell-скрипт на Perl. Это потенциально может устранить дополнительную работу по разбору выходных данных (разбиение их на строки и отделение значений из этих строк в массив, потому что вы можете записывать данные непосредственно в массив (или, возможно, распечатывать свои HTML-строки) непосредственно во время их генерации (однако это делает ваш существующий сценарий оболочки).
Ответ №2:
Чтобы записать выходные данные вашего файла bash, вы можете использовать оператор возврата:
use strict;
my $e = `ls`;
print $e;
Комментарии:
1. Да, но если у него нет опыта работы с Perl, по крайней мере, включите
use strict
и сделайтеmy $e =
🙂
Ответ №3:
Большое, огромное спасибо вам! С вашей огромной помощью. Я смог создать perl-скрипт, который выполняет большую часть работы.
Это то, что я создал до сих пор:
#!/usr/bin/perl -w
use strict;
use CGI qw(:standard);
#some variables
my $message = "please wait, loading data...n";
#First build the web page
print header;
print start_html('Hello World');
print "<H1>we need love, peace and harmony</H1>n";
print "<p>$message</p>n";
#Establish a pipeline between the bash and my script.
my $bash_command = '/love/peace/harmony/./lovepeace.bash';
open(my $pipe, '-|', $bash_command) or die $!;
while (my $line = <$pipe>){
# Do something with each line.
print "<p>$line</p>n";
}
#job done, now refresh page?
print end_html;
Когда я вызываю этот скрипт .pl в своем браузере, все работает нормально 🙂 Но несколько вопросов все еще у меня на уме:
Когда я вызываю этот веб-сайт, он занят загрузкой значений из канала. Поскольку существует около 10 значений, его скорее
быстро (2-4 секунды) Но если у меня более 100 значений, пользователю приходится некоторое время ждать. Поскольку у меня не может быть индикатора выполнения, я
должен предоставить информацию пользователю. Нравится:
«Загрузка данных, пожалуйста, подождите …»
И когда задание будет выполнено, в этом сообщении должно быть написано: «Задание выполнено» или что-то подобное.
- Но как мне понять, завершен ли процесс?
- могу ли я перезагрузить страницу, если задание выполнено?
- Есть ли какая-нибудь возможность использовать мою собственную таблицу стилей с этим perl-CGI
С уважением,
JJ
Комментарии:
1. Я бы посоветовал вам создать новый вопрос для этого.
Ответ №4:
Почему только perl:
вы можете использовать awk для этого в стороне от самого вашего shell-скрипта. Я делал это ранее. если у вас есть исходящие значения в переменной, тогда используйте приведенный ниже метод:
echo $SUBSCRIBERS|awk 'BEGIN {
print "<?xml version="1.0" encoding="UTF-8"?><GenTransactionHandler xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><EntityToPublish>n<Entitytype="C" typeDesc="Subscriber level"><TargetApplCode>UHUNLD</TargetApplCode><TrxName>GET_SUBSCR_DATA</TrxName>"
}
{for(i=1;i<NF 1;i ) printf("<value>%d</value>n",$i)}
END{
print "</Entity>n</EntityToPublish></GenTransactionHandler>"}' >XML_SUB_NUM`date %Y%m%d%H%M%S`.xml
в $SUBSCRIBERS
значения должны быть разделены табуляцией eb.