首页 > 解决方案 > 来自我的 Perl 脚本的系统调用会截断地址

问题描述

我在 Perl 脚本中有以下行,它进行系统调用:

system("ssh root@10.48.13.20 /usr/sbin/asterisk -rx 'rpt playback 1101 /etc/asterisk/audio/newsfiles/newstonight'");

调用时,Perl 报告:

ssh:无法解析主机名 root.48.13.20:名称或服务未知

被调用的计算机与运行脚本的计算机位于同一网络上(我可以 ping 它等) 问题是 IP 被截断。我确定这是我做错了什么愚蠢的事情,也许就像不得不逃避“@”?

标签: perl

解决方案


你有几个答案,但没有人详细解释这个问题。

你有一个双引号字符串:

"ssh root@10.48.13.20 /usr/sbin/asterisk -rx 'rpt playback 1101 /etc/asterisk/audio/newsfiles/newstonight'"

双引号字符串的有用之处之一是 Perl 会在其中找到任何变量并将它们替换为这些变量的当前值。

你的字符串中有一些看起来像变量的东西。是@10。这看起来像一个名为“10”的数组。所以 Perl 试图将那个变量的内容插入到字符串的那个部分。我猜你@10的代码中没有调用数组 - 所以变量最终被一个空字符串替换,你最终得到一个看起来像这样的字符串:

"ssh root.48.13.20 /usr/sbin/asterisk -rx 'rpt playback 1101 /etc/asterisk/audio/newsfiles/newstonight'"

这是胡说八道,只是行不通(并且还解释了您看到的错误)。

有几种方法可以解决这个问题。首先你可以逃避,@所以 Perl 不再认为它是变量的开始。

"ssh root\@10.48.13.20 /usr/sbin/asterisk -rx 'rpt playback 1101 /etc/asterisk/audio/newsfiles/newstonight'"

但实际上,我想说,如果这不需要是双引号字符串(我认为不需要),你应该把它放在单引号中。当然,由于您的字符串中已经有单引号,因此您必须将它们换成双引号:

'ssh root@10.48.13.20 /usr/sbin/asterisk -rx "rpt playback 1101 /etc/asterisk/audio/newsfiles/newstonight"'

另一种选择是使用q[...]运算符创建一个单引号字符串而不实际使用单引号:

q[ssh root@10.48.13.20 /usr/sbin/asterisk -rx 'rpt playback 1101 /etc/asterisk/audio/newsfiles/newstonight']

最后,值得指出的是,如果您的代码中有(并且use strict您应该始终在您的代码中),那么它会知道您没有调用变量,并会给您一个有用的错误消息并阻止您的程序运行直到你修复它。use strictuse warnings@10

更新:我还应该提到北极熊的答案是最好的方法。给出system()一个字符串列表而不是一个字符串将提高安全性,因为 Perl 将直接运行外部程序,而不是启动一个新的 shell 来运行它。


推荐阅读