例如,我有一个比我预期的更快填充的大型文件系统.所以我寻找正在添加的内容:
find /rapidly_shrinking_drive/ -type f -mtime -1 -ls | less
Run Code Online (Sandbox Code Playgroud)
而且我发现很多东西.成千上万的六七种文件.我可以挑出一个类型并计算它们:
find /rapidly_shrinking_drive/ -name "*offender1*" -mtime -1 -ls | wc -l
Run Code Online (Sandbox Code Playgroud)
但我真正喜欢的是能够获得这些文件的磁盘总大小:
find /rapidly_shrinking_drive/ -name "*offender1*" -mtime -1 | howmuchspace
Run Code Online (Sandbox Code Playgroud)
如果有人有,我会对Perl单行开放,但是我不打算使用任何涉及多行脚本或File :: Find的解决方案.
是的,问题出在我正在使用的库中,不,我无法修改它.我需要一个解决方法.
基本上,我正在处理一个写得很糟糕的Perl库,当遇到读取文件的某个错误条件时,它会以'die'退出.我从一个程序中调用这个例程,该程序循环遍历数千个文件,其中一些文件很糟糕.坏文件发生; 我只想让我的例程记录错误并继续前进.
如果我可以修改库,我只需更改
die "error";
Run Code Online (Sandbox Code Playgroud)
到了
print "error";return;
Run Code Online (Sandbox Code Playgroud)
, 但是我不能.有什么方法可以解决这个例程,以便坏文件不会崩溃整个过程?
关注问题:使用"eval"来解决容易崩溃的调用很有效,但是如何在该框架内设置可捕获错误的处理?来描述:
我有一个子程序调用库 - 崩溃 - 有时很多次.而不是使用eval {}在这个子例程中调用每个调用,我只是让它死掉,并在调用我的子例程的级别上使用eval {}:
my $status=eval{function($param);};
unless($status){print $@; next;}; # print error and go to next file if function() fails
Run Code Online (Sandbox Code Playgroud)
但是,我可以在函数()中捕获错误条件.在子例程和调用例程中设计错误捕获的最恰当/优雅的方法是什么,以便我获取捕获和未捕获错误的正确行为?
多年来,我一直在Perl中编程,不过几年,虽然只是偶尔使用它是我的主要语言.因为我经常在几个月没有写任何perl,所以我非常依赖我的狗耳骆驼书来提醒我如何做事.然而,当我逐字逐句地复制食谱时,这让我感到困扰.这是最令人头疼的问题之一:在第3版Camel的第154页,有一个"修改字符串en passant的例子,其内容如下:
($lotr = $hobbit) =~ s/Bilbo/Frodo/g;
Run Code Online (Sandbox Code Playgroud)
Q1)这里发生了什么?究竟什么是正则表达式运作?
Q2)这种近乎神奇的语法是否需要这样的基本操作:"从$ a中取一个字符串,用正则表达式修改它,将结果放在$ b中"?
Q3)如何使用循环默认变量作为初始字符串来执行此操作?
向Perl梦想家道歉,上面看起来非常自然.
这是"如何在Perl库中绕过'die'调用我无法修改?"的后续内容..
我有一个子程序,它调用一个库 - 崩溃 - 有时很多次.而不是使用eval {}在这个子例程中调用每个调用,我只是让它死掉,并在调用我的子例程的级别上使用eval {}:
my $status=eval{function($param);};
unless($status){print $@; next;}; # print error and go to
# next file if function() fails
Run Code Online (Sandbox Code Playgroud)
但是,我可以在函数()中捕获错误条件.在子例程和调用例程中设计错误捕获的最恰当/优雅的方法是什么,以便我获取捕获和未捕获错误的正确行为?
所以,我的代码(Perl脚本和Perl模块)就像这样一棵树:
trunk/
util/
process/
scripts/
Run Code Online (Sandbox Code Playgroud)
'util'目录有实用程序,'process /'目录中的东西需要.他们像这样访问:
use FindBin;
use lib "$FindBin::Bin/../util";
use UtilityModule qw(all);
Run Code Online (Sandbox Code Playgroud)
只要你在树中与"util /"处于同一级别,那个结构并不关心你从哪里开始.
但我觉得'scripts /'过于拥挤,所以我创造了
scripts/scripts1
scripts/scripts2
Run Code Online (Sandbox Code Playgroud)
现在我看到这不起作用.如果我运行脚本'trunk/scripts/scripts1/call_script.pl',并且它调用'/trunk/process/process_script.pl',那么'process_script.pl'将无法尝试从UtilityModule()获取例程,因为FindBin返回的路径是顶级调用脚本的路径.
我想到的解决这个问题的前十种方法都涉及到:
use lib $path_that_came_from_elsewhere;
Run Code Online (Sandbox Code Playgroud)
但这似乎是Perl不喜欢做的事情,除了通过FindBin技巧.
我尝试了一些涉及BEGIN {}块的事情,但我真的不知道我在那里做什么,并且很可能最终会重构.但如果有人对这类问题有一些聪明的洞察力,那么这将是获得一些积分的好机会!
我想使用Perl脚本批处理用system()调用的重复操作.当出现问题并且我想要中断这个脚本时,shell会捕获^ C,停止任何工作,并且Perl脚本会快速地转到下一个脚本.
有没有办法可以调用作业,以便中断将停止Perl脚本?
那么,好吧,作业在cron中运行:它获取压缩文件并处理它们.如果文件已损坏,则会删除它们.有时它们在远程服务器上很糟糕,在这种情况下,每次都会下载和删除它们.
我的cron广泛记录到STDOUT(定向到.crontab中的logfile),使用STDERR仅用于导致脚本停止的事情:我喜欢在发生坏事时从cron收到电子邮件; 只是损坏的文件不应该在此列表中.
我需要'gunzip'的输出告诉我文件是否已损坏.但是,我厌倦了每次遇到错误的文件时都会收到来自cron的电子邮件.如何调用'gunzip'以便错误不会触发来自cron的电子邮件,同时仍然让调用'gunzip'的脚本知道它失败了?
这可能是一个非常简单的,但我对这个cron的东西很新.
重要PS:'gunzip'是从Perl脚本调用的,使用
$gunzip_result=system("gunzip $gzfile");
if($gunzip_result){
print,"$gzfile is bad: deleting...\n";
unlink $gzfile;
};
Run Code Online (Sandbox Code Playgroud)