【发布时间】:2017-11-23 13:05:21
【问题描述】:
我正在尝试制作一个像 Perl 中非常简单的服务器一样工作的程序。
该程序本身旨在用作图书馆目录,为用户提供按书名或作者搜索书籍以及借阅或归还书籍的选项。图书列表在单独的文件中提供。
基本上,它应该从“Requests”文件夹中获取请求(文件),处理它们,然后在“Answers”文件夹中给出答案(也是文件)。该过程结束后,它会删除旧的请求并重复该过程(答案被客户端接受后将被删除)。
它本来是作为守护进程运行的,但由于某种原因,只有负责删除请求文件的循环在后台工作——请求不会被处理成答案,而只是被删除。每当出现新请求时,它几乎会立即被删除。
我正在学习使用守护进程并尝试模拟this thread 中的内容。
#!/usr/bin/perl
use warnings;
use strict;
use Proc::Daemon;
#FUNCTIONS DEFINTIONS
sub FindAuthor
{
#try to find book by this author in the catalogue
}
sub FindTitle
{
#try to find book with this title in the catalogue
}
sub CheckIfCanBeReturned
{
#check if the book is borrowed and by whom
}
#attempt at daemonization
Proc::Daemon::Init;
my $continueWork = 1;
$SIG{TERM} = sub { $continueWork = 0 };
while ( $continueWork )
{
sleep(2);
my @RequestFilesArray = `ls /home/Ex5/Requests`;
#list all requests currently in the Request folder
for ( my $b = 0; $b < @RequestFilesArray; $b++)
{
my $cut = `printf "$RequestFilesArray[$b]" | wc -m`;
$cut = $cut - 1;
$RequestFilesArray[$b] = substr $RequestFilesArray[$b], 0, $cut;
}
#the requests are formatted in such way,
#that the first 2 letters indicate what the client wants to be done
#and the rest is taken parameters used in the processing
for (my $i = 0; $i < @RequestFilesArray; $i++)
{
my $UserRequest = `tail -1 Requests/$RequestFilesArray[$i]`;
my $fix = `printf "$UserRequest" | wc -m`;
$fix = $fix - 1;
$UserRequest = substr $UserRequest, 0, $fix;
my $RequestType = substr $UserRequest, 0, 2;
my $RequestedValue = substr $UserRequest, 3;
my $RequestNumber = $i;
if ($RequestType eq "fa")
{
#FIND BY AUTHOR
my @results = FindAuthor ($RequestedValue);
my $filename = "/home/Ex5/Answers/" . $RequestFilesArray[$RequestNumber];
open (my $answerFile, '>', $filename) or die "$!";
for (my $a = 0; $a < @results; $a++)
{
print $answerFile $results[$a],"\n";
}
close $answerFile;
}
elsif ($RequestType eq "ft")
{
#FIND BY TITLE
my @results = FindTitle ($RequestedValue);
my $filename = "/home/Ex5/Answers/" . $RequestFilesArray[$RequestNumber];
open ( my $answerFile, '>', $filename) or die "$!";
for (my $a = 0; $a < @results; $a++)
{
print $answerFile $results[$a],"\n";
}
close $answerFile;
}
elsif ($RequestType eq "br")
{
#BOOK RETURN
my $result = CheckIfCanBeReturned ($RequestedValue, $RequestFilesArray[$RequestNumber]);
my $filename = "/home/Ex5/Answers/" . $RequestFilesArray[$RequestNumber];
open ( my $answerFile, '>', $filename) or die "$!";
print $answerFile $result;
close $answerFile;
}
elsif ($RequestType eq "bb")
{
#BOOK BORROW
my $result = CheckIfCanBeBorrowed ($RequestedValue, $RequestFilesArray[$RequestNumber]);
my $filename = "/home/Ex5/Answers/" . $RequestFilesArray[$RequestNumber];
open ( my $answerFile, '>', $filename) or die "$!";
print $answerFile $result;
close $answerFile;
}
else
{
print "something went wrong with this request";
}
}
#deleting processed requests
for ( my $e = 0; $e < @RequestFilesArray; $e++)
{
my $removeReq = "/home/Ex5/Requests/" . $RequestFilesArray[$e];
unlink $removeReq;
}
#$continueWork =0;
}
【问题讨论】:
-
请提供一个最小的、可运行的问题演示。
-
将错误发送到
/dev/null会使调试变得相当困难。你应该先解决这个问题! -
尝试添加调试
print语句,以便查看变量的值。 -
我看到了几个问题,但我看到的最大的问题是
execing 调用tail、ls和printf(哇?Perl 有一个printf)。我建议使用 Perl 迭代数组的能力与传统的for-loopIEfor my $item ( @RequestFilesArray )相比,虽然这不一定是错误的。我还建议将您的sleep(2)放在循环的末尾,而不是前面。我模仿我之前的其他人说的话。您应该使用glob()来获取您的文件列表。请回答@ikegami 的问题。 -
@Jim,这是一个正确且记录在案的用法。也就是说,指示它将 STDERR 重定向到实际文件而不是默认的
/dev/null会更有用。