在 Perl 中编码时真的应该使用外部命令吗?我看到了它的几个缺点。它不是独立于系统的,还可能存在安全风险。你怎么看?如果没有办法,您必须使用 Perl 的 shell 命令,那么执行该特定命令的最安全方法是什么(例如检查 pid、uid 等)?
3 回答
这取决于在 Perl 中复制功能的难度。如果我需要m4
在某些东西上运行宏处理器,我不会考虑自己尝试在 Perl 中复制该功能,并且由于http://search.cpan.org/上没有看起来合适的模块,它会出现其他人同意我的观点。在这种情况下,使用外部程序是明智的。另一方面,如果我需要读取目录的内容,那么在 Perl 中结合使用readdir()
et al plus stat()
orlstat()
比使用ls
.
如果您需要执行命令,请仔细考虑如何调用它们。特别是,您可能希望避免 shell 解释参数,因此请使用数组形式system
(另请参阅exec
)等,而不是命令加参数的单个字符串(这意味着 shell 用于处理命令行) .
执行外部命令可能很昂贵,因为它涉及派生新进程并在需要时监视其输出。
可能更重要的是,如果外部进程因任何原因失败,可能很难通过您的脚本来理解发生了什么。更糟糕的是,令人惊讶的是,外部进程经常会永远卡住,您的脚本也会如此。您可以使用特殊技巧,例如打开管道并在循环中观察输出,但这本身很容易出错。
Perl 非常有能力做很多事情。所以,如果你坚持只使用 Perl 原生结构和模块来完成你的任务,不仅它会更快,因为你从不分叉,而且通过查看由库例程。当然,它会自动移植到不同的平台。
如果您的脚本在提升的权限下运行(如 root 或在 sudo 下),您应该非常小心您执行的外部程序。确保基本安全性的简单方法之一是始终按全名指定命令,例如 /usr/bin/grep (但仍要三思而后行,只需通过 Perl 本身执行 grep!)。但是,如果攻击者使用 LD_PRELOAD 机制注入恶意共享库,即使这样也可能还不够。
如果您愿意非常安全,建议通过使用 -T 标志来使用污染检查,如下所示:
#!/usr/bin/perl -T
如果您的脚本被确定为具有不同的真实有效的用户或组 ID,Perl 也会自动启用污点标志。
污染模式将严重限制您在没有 Perl 抱怨的情况下执行许多操作(如 system() 调用)的能力 - 更多信息请参见http://perldoc.perl.org/perlsec.html#Taint-mode,但它会给您更高的安全信心。
在 Perl 中编码时真的应该使用外部命令吗?
这个问题没有单一的答案。这一切都取决于您在 Perl 的广泛潜在用途中所做的工作。
你是在本地机器上使用 Perl 作为一个美化的 shell 脚本,还是只是想找到一个快速而肮脏的解决方案来解决你的问题?在这种情况下,如果这是完成任务的最简单方法,那么运行系统命令就很有意义。安全性和速度不是那么重要;重要的是快速编码的能力。
另一方面,您正在编写生产程序吗?在这种情况下,您需要安全、可移植、高效的代码。通常最好在 Perl 中编写功能(或使用模块),而不是调用外部程序。至少,您应该认真考虑一下优点和缺点。