while 循环内的 Perl bash 命令产生无意义的结果
你好 stackpeople!
我有两件事需要解决并在 cgi 文件中在线显示结果。
A) 获取给定路径上的所有文件夹名称
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/ 中所有文件夹名称的一个很好的列表
现在,在浏览器中显示此输出的 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}`
这给了我完美的输出:Feb 22 10:56 现在我需要在我的表中提供这些信息。我已在 while 循环内的 perl 脚本中添加了这一行:
$timestamp = `ls -ltr /test/folder1/*.html | tail -1 | awk '{printf"%3s %1s %s\\n",\$6, \$7, \$8}`;
当我将文件夹名称添加为字符串时,这非常有效。一旦我将 folder1 与 $foldername 交换,我就会得到无意义的“ls”信息。
为什么会这样呢?
编辑:现在我已经使用:
use File::stat;
use Time::localtime;
my $timestamp = ctime(stat("/test/folder1")->mtime);
与解析 ls 输出相比,这更安全。但我对 $foldername 仍然有疑问。我使用了 length 函数来确定 $Foldername 的长度。
$foldername 的长度为 7,但字符串输出只有 6 个字符:tomato
所以我尝试了 Chop/chomp $foldername ,结果始终相同:7 个字符!
Hello stackpeople!
I have 2 things to solve and display the results online in a cgi-file.
A) get all foldernames at a given path
B) determine the age of the index.html inside each folder
the result should look like this:
[Number] [Foldername] [fileage]
This cgi-page runs on a solaris server with installed perl 5.8.4
My solution is a combination of bash and perl. To solve problem A) (the folder names) I have written a bash script:
#!/bin/bash
#
find /test/ -type d | sed -e 's/^.*\///'
This gives me a nice list of all foldernames in /test/
Now the perl code to show this output in a browser:
#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
This works! I'll get a nice table with [Number] and [Foldername] ! Now comes the tricky part! In addition, I want the date of an index.html located in each folder. Therefore I have another bash script:
ls -ltr /test/folder1/*.html | tail -1 | awk '{printf"%3s %1s %s\n",$6, $7, $8}`
This gives me the perfect output: Feb 22 10:56 Now I need this information in my table. I have added this line in my perl script within the while loop:
$timestamp = `ls -ltr /test/folder1/*.html | tail -1 | awk '{printf"%3s %1s %s\\n",\$6, \$7, \$8}`;
This works perfect when I add the foldername as a string. As soon as I exchange folder1 with $foldername I'll get nonsense "ls" information.
Why is that so?
Edit: Now I have used:
use File::stat;
use Time::localtime;
my $timestamp = ctime(stat("/test/folder1")->mtime);
This is way more secure compared to parsing the ls output. But still I have issues with the $foldername. I have used the length function to determine the length of $Foldername.
$foldername has a length of 7, but the string output has only 6 chars: tomato
So I've tried Chop/chomp the $foldername with always the same result: 7 chars!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
首先,不要以编程方式解析
ls
输出。它几乎肯定会在某个时刻破裂,并且以某种惊人的方式破裂。解析 find 的输出只是稍微安全一些(例如,大多数 Unix 上的目录名称可以包含换行符;我认为您的代码不能很好地处理这种可能性)。Perl 有一个
stat
函数,它会给你日期和任何文件或目录的时间(atime、mtime 或 ctime,如果可用),以及一堆其他信息。然后,您可以使用类似strftime
来设置这些时间戳的格式以获得更好的输出。Firstly, don't parse
ls
output programmatically. It's nearly guaranteed to break at some point, and to do so in some spectacular fashion. Parsing the output offind
is only marginally safer (directory names on most Unixes can contain newline characters, for example; I don't see your code dealing well with that possibility).Perl has a
stat
function which will give you the date and time of any file or directory (atime, mtime, or ctime, as available), as well as a bunch of other information. You can then use something likestrftime
to format these timestamps for nicer output.我认为您会得到不同的输出,因为
$foldername
不包含"folder1"
。事实上,看看你之前的代码,你缺乏
chomp
ing 表示$foldername
更有可能包含"folder1\n"
。请注意,如果
$foldername
包含空格,您的方法将会失败,这在当今是一个相当愚蠢的限制。查看stat
或 文件::stat。I presume you get different output because
$foldername
doesn't contain"folder1"
.In fact, looking at your earlier code, your lack of
chomp
ing would indicate that$foldername
is far more likely to contain"folder1\n"
.Note that your approach will fail if
$foldername
contains a space, which is a pretty dumb limitation these days. Check outstat
or File::stat.