我的 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 &gt;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(有少数例外)。 foreachwhile 容易吗?更糟糕的是,当您在列表上下文中调用 &lt;&gt; 时,您会将整个文件读入内存,这完全没有必要,因为您只是逐行遍历它。正如 Kenosis 所说,使用词法文件句柄 (my $fh) 而不是类型球 (FH),它们是全局范围的。 我想当我说“更容易”时,我的意思是这是我遍历列表的首选方式。 While 没问题,但我更喜欢在谈论满足条件时使用它 (while $a = true) 我认为 Perl 的优势之一是它冗长的语法,你几乎可以写出实际的句子 foreach $line ( @list ) 至于使用词法文件句柄 - 再次使用 typeglobs我从小就使用的东西,是我的首选语法。它必须是一个巨大的 IP 列表才能对内存资源产生重大影响。在这种情况下,测试会揭示它,并且需要重新考虑。 拥有自己的个人喜好很好,但您在公共论坛上宣传不良做法。也许你不知道why you shouldn't use typeglobs。至于内存,如果你能保证你的输入文件总是很小,即使你已经停止维护代码并且它被用于你从未预料到的事情,无论如何,把它塞进内存。我不能保证我写的代码。再说了,while (my $row = &lt;$fh&gt;)真的那么难读吗?

以上是关于我的 Perl 有多糟糕?获取 IP 地址并返回完全限定域名的脚本 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

在python中读取Fuse的实现没有按预期返回,cat: :糟糕的地址

通过网络请求获取当前IP,并得到大致位置

学好perl脚本对你的职业发展有多重要?

获取机器上的所有 IP 地址

需要在 perl 中从远程机器获取 Oracle 和 MySQL 的版本

我可以获取flask_ngrok或py-ngrok生成的ip地址或域名并返回到127.0.0.1/