Выполнение скрипта bash, чтение его выходных данных и создание html с помощью Perl

#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.