我的 Perl 有多糟糕?获取 IP 地址并返回完全限定域名的脚本 [关闭]
Posted
技术标签:
【中文标题】我的 Perl 有多糟糕?获取 IP 地址并返回完全限定域名的脚本 [关闭]【英文标题】:How terrible is my Perl? Script that takes IP addresses and returns Fully Qualified Domain Names [closed] 【发布时间】:2014-04-09 10:32:55 【问题描述】:我邀请你,给我撕一个新的。
这段代码完成了工作。它需要一个包含 IP 列表的 .txt 文件,并写入一个包含它们各自的完全限定域名的文件。
我想知道这段代码在哪些方面写得不好。这里有什么坏习惯?
我是 perl 和编程新手。我设法使用谷歌和跟踪和错误把它放在一起。让它工作很令人满意,但请告诉我如何改进。
use strict;
use warnings;
use Socket;
use autodie;
my $filename = 'IPsForFQDN.txt';
#File with list of IPs to lookup.
#One IP address per line like so:
#10.10.10.10
#10.10.10.11
#10.10.10.12
#etc...
open(my $fh, '<:encoding(UTF-8)', $filename)
or die "Could not opne file '$filename' $!";
my $fqdn = '';
while (my $row = <$fh>)
chomp $row;
print "$row\n";
$fqdn = gethostbyaddr(inet_aton($row), AF_INET);
print $fqdn;
print "\n";
open FILE, ">>fqdn.txt" or die $!;
print FILE $fqdn;
print FILE "\n";
close FILE;
print "done\n";
例如是否需要 chomp $row; 行?我不知道它是做什么的。
我同样对整个 or die $!; 事情感到迷惑。
【问题讨论】:
如果您的代码已经在运行,这个问题更适合codereview.stackexchange.com。 看起来不错。我没有什么要告诉你Perl::Critic
不会说的。
单线候选人很简单:perl -MSocket -nwe 'my $fqdn = gethostbyaddr(inet_aton($_), AF_INET); print $fqdn? $fqdn :"", "\n";' IPsForFQDN.txt >fqdn.txt
【参考方案1】:
$!
报告失败的原因。在这里,如果您无法打开文件,则会指出失败的原因。 perlvar 在error variables 上有一个部分。
您正在使用chomp 删除每行末尾的换行符。
在编写文件时调用 open 略有不同,请考虑使用与打开代码时使用相同的 3 参数版本(另请参阅我为打开提供的链接),并使用相同的编码风格。保持一致就好,而且这种方法更安全。
【讨论】:
【参考方案2】:你为你写的每一行重复打开fqdn.txt
。我只是在循环之前打开它并在最后关闭它。
哦 - 而且您使用的是 autodie,所以 or die
应该不是必需的。
哦 - 与新式打开阅读文件相比,您也使用了旧式 open
。
【讨论】:
【参考方案3】:工作上没有太多进展,所以我尝试用 cmets 进行一些重写以解释一些事情。不正确/不错误只是我的旋转和我们在我的地方使用的一些标准已经添加。
希望这会有所帮助...
use strict;
use warnings;
use Socket;
# initialize variables here.
my $filename = "IPsForFQDN.txt";
# open both file handles - once only
# Note safer expression using 2 commas
open(FH, "<", $filename)
or die "Could not opne file '$filename' $!";
# open FILE for appending
open FILE, ">>", "fqdn.txt" or die $!;
# use foreach instead of while - easier syntax (may provoke discussion ;-) )
# replaced $fh for FH - use file handles throughout for consitency
foreach my $row ( <FH> )
chomp $row;
# put a regex check in for comments
if( $row !~ m/^#/ )
printf ("Row in file %s \n", $row );
# initialize $fqdn here to keep it fresh
my $fqdn = gethostbyaddr(inet_aton($row), AF_INET);
# formatted print to screen (STDOUT)
printf ("FQDN %s \n", $fqdn);
# formatted print to output file
printf FILE ("%s \n", $fqdn);
# close both file handles - once only
close FILE;
close FH;
print "done\n";
【讨论】:
哦,是的,在几个地方我将单引号换成了双引号,以保持始终一致。此外,我更喜欢使用双引号而不是单引号 - 这源于 UNIX 系统不会用单引号替换变量的方式#MyIssueWithSingleQuotes :) 作为标准,在opening 文件时考虑采用词法文件句柄,并避开bareword file handles(有少数例外)。foreach
比while
容易吗?更糟糕的是,当您在列表上下文中调用 <>
时,您会将整个文件读入内存,这完全没有必要,因为您只是逐行遍历它。正如 Kenosis 所说,使用词法文件句柄 (my $fh
) 而不是类型球 (FH
),它们是全局范围的。
我想当我说“更容易”时,我的意思是这是我遍历列表的首选方式。 While
没问题,但我更喜欢在谈论满足条件时使用它 (while $a = true)
我认为 Perl 的优势之一是它冗长的语法,你几乎可以写出实际的句子 foreach $line ( @list )
至于使用词法文件句柄 - 再次使用 typeglobs我从小就使用的东西,是我的首选语法。它必须是一个巨大的 IP 列表才能对内存资源产生重大影响。在这种情况下,测试会揭示它,并且需要重新考虑。
拥有自己的个人喜好很好,但您在公共论坛上宣传不良做法。也许你不知道why you shouldn't use typeglobs。至于内存,如果你能保证你的输入文件总是很小,即使你已经停止维护代码并且它被用于你从未预料到的事情,无论如何,把它塞进内存。我不能保证我写的代码。再说了,while (my $row = <$fh>)
真的那么难读吗?以上是关于我的 Perl 有多糟糕?获取 IP 地址并返回完全限定域名的脚本 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章
在python中读取Fuse的实现没有按预期返回,cat: :糟糕的地址