while循环中的Perl bash命令产生无意义

时间:2012-02-22 10:14:12

标签: perl while-loop

Hello stackpeople!

我有两件事需要解决,并在cgi文件中在线显示结果。

A)获取指定路径下的所有foldernames

B)确定每个文件夹中index.html的年龄

结果应如下所示:

[Number] [Foldername] [fileage]

此cgi页面在安装了perl 5.8.4的solaris服务器上运行

我的解决方案是bash和perl的组合。要解决问题 A)(文件夹名称)我写了一个bash脚本:

#!/bin/bash
#
find /test/ -type d | sed -e 's/^.*\///'

这给了我一个很好的/ test /

中所有foldernames的列表

现在在浏览器中显示此输出的perl代码:

  #Establish a pipeline between the bash and my script.
  my $bash_command = '/test./foldernames.bash';
  open(my $pipe, '-|', $bash_command) or die "Can't open pipe: $!";
  # initialize variables
   my $foldername = "";
   my $i    = 0;

  # Process the output from bash command line by line.
  while (my $line = <$pipe>)
  {
   $foldername = $line;
   $i = $i+1;

   print"  <tr><td>$i</td><td>$foldername</td></tr>";
 }#end while

这个有效!我会用[Number]和[Foldername]得到一张漂亮的桌子!现在是棘手的部分!另外,我想要每个文件夹中的index.html的日期。因此我有另一个bash脚本:

ls -ltr /test/folder1/*.html | tail -1 | awk '{printf"%3s %1s %s\n",$6, $7, $8}`

这给了我完美的输出: 2月22日10:56 现在我在表格中需要这些信息。我在while循环中的perl脚本中添加了这一行:

$timestamp = `ls -ltr /test/folder1/*.html | tail -1 | awk '{printf"%3s %1s %s\\n",\$6, \$7, \$8}`;

当我将foldername作为字符串添加时,这非常有效。只要我用 $ foldername 交换 folder1 ,我就会收到无意义的“ls”信息。

为什么会这样?

编辑:现在我使用了:

use File::stat;
use Time::localtime;
my $timestamp = ctime(stat("/test/folder1")->mtime);

与解析ls输出相比,这更安全。但我仍然遇到$ foldername的问题。我使用长度函数来确定 $ Foldername 的长度。

$ foldername的长度为7,但字符串输出只有6个字符:tomato

所以我尝试了Chop / chomp $ foldername,总结果相同:7个字符!

2 个答案:

答案 0 :(得分:4)

首先,不以编程方式解析ls输出。它几乎可以保证在某个时刻突破,并以一种惊人的方式这样做。解析find的输出只是稍微安全一些(例如,大多数Unix上的目录名都可以包含换行符;我看不到你的代码处理这种可能性)。

Perl有a stat function,它将为您提供任何文件或目录的日期和时间(atime,mtime或ctime,如果可用),以及一堆其他信息。然后,您可以使用类似strftime的内容来格式化这些时间戳,以获得更好的输出。

答案 1 :(得分:2)

我认为你得到的输出不同,因为$foldername不包含"folder1"

事实上,在查看您之前的代码时,缺少chomp会表明$foldername更有可能包含"folder1\n"

请注意,如果$foldername包含空格,那么您的方法将会失败,这是一个非常愚蠢的限制。查看statFile::stat