执行bash脚本,读取其输出并使用Perl创建html

时间:2011-04-27 09:31:44

标签: perl bash

我有一个bash脚本,它产生不同的整数值。当我运行该脚本时,输出如下所示:

12

34

34

67

6

此脚本在Solaris服务器上运行。为了向网络中的其他用户提供这些值,我决定编写一个Perl脚本,该脚本可以:

  • 运行bash文件
  • 阅读其输出
  • 构建一个小的html页面,其中包含存储bash值的表格

这对我来说很难,因为我几乎没有使用Perl的经验。我知道我可以使用系统来执行unix命令(和bash文件),但我无法获得输出。我也听说过 qx ,这对我的情况非常有用。

但我必须承认我不知道如何开始...你能给我一些提示如何解决这个问题吗?

4 个答案:

答案 0 :(得分:3)

有了这样的问题,有点难以知道从哪里开始。

您引用的qx是Perl的一项功能。 Perl“运算符”手册页中记录了“q *”或“引用和引用类操作符”(通常,您使用man perlop在具有传统Perl安装的系统上读取它。) p>

具体来说qx是“命令的引用执行”......它本质上是Perl中`(后退或“命令替换”)运算符的替代形式。

换句话说,如果执行如下命令:

perl -e'$ foo = qx {ls};打印“\ n ### \ n $ foo \ n ### \ n”;'

...在安装了Perl的系统上然后它应该运行Perl,它应该评估(-e)你提供的表达式(引用)。换句话说,我们正在命令行上编写一个小程序。该程序首先创建一个变量,其内容将是“标量”(这是字符串或数字的Perl术语)。我们将通过执行ls命令捕获的输出(=,或赋值运算符)分配回此变量($ foo)。之后我们打印变量的内容(无论ls命令打印了什么),在这些内容之前和之后都有###行。

Perl的qx运算符(以及其他各种q *运算符)的一个怪癖是,它允许您使用您喜欢的任何字符来分隔命令。例如,perl -e '$bar = qx/pwd/;'将捕获pwd命令的输出。当您使用通常用作文本括号,大括号,括号等的分隔符的任何字符时,qx命令将查找适当的匹配分隔符。如果你使用任何其他标点符号(或非字母数字字符?),那么同一个字符也将是终止分隔符。后来的行为与旧sed实用程序和ed行编辑器中的“替换”命令中的功能类似,并受其启发;而圆括号,括号等的匹配是Perl的新颖性。

这就是如何捕获shell脚本输出的基础知识。要在HTML表格中打印数字,您必须将捕获的输出拆分为单独的行(将它们保存到列表或数组中),然后打印HTML序言(<table><th>(标题)标签,等等)...它们遍历一系列<tr>行,将您的数字插入<td>>(表数据)容器中,然后最后打印您的HTML结尾(带结束标记)

为此,您需要阅读Perl print函数以及Perl中的“插值”。这是一个相当复杂的话题。

这一切都非常粗糙,并且有一些工具可以让您在更高的层次上处理HTML的生成。您希望将shell脚本的执行包装在Perl脚本中也是相当可疑的,因为您似乎可以修改shell脚本以直接输出HTML(可能作为由命令行开关或环境变量控制的选项)或您可以在Perl中重写shell脚本。这可能会消除解析输出的额外工作(将其拆分为行并将这些行中的值分离成数组,因为您可以直接将数据直接捕获到数组中(或者可能打印出您的HTML行)生成它们(但是现有的shell脚本正在执行此操作)。

答案 1 :(得分:1)

要捕获bash文件的输出,可以使用反引号运算符:

use strict;
my $e = `ls`;
print $e;

答案 2 :(得分:0)

为什么只有perl:

你可以在你的shell脚本本身使用awk。 我之前做过这个。 如果您在变量中有输出值,则使用以下方法:

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标签分隔。

答案 3 :(得分:0)

很多,非常感谢你!在你的帮助下。我能够构建一个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