在perl脚本中使用shell命令会产生不同的结果
我有一个perl脚本,需要检查远程机器上的空目录。使用ksh,我可以使用以下shell脚本:在perl脚本中使用shell命令会产生不同的结果,perl,ssh,Perl,Ssh,我有一个perl脚本,需要检查远程机器上的空目录。使用ksh,我可以使用以下shell脚本: ksh# ssh user@host '[ "$(ls -A /empty/dir/* 2>/dev/null)" ] && echo "1" || echo "0"' 如果目录为空或不存在,则正确返回“0”。仅当目录包含某些内容时,它才会返回“1” 当我将这一行放在perl脚本中时,就像这样: #!/usr/bin/perl print `ssh user\@host '[ "
ksh# ssh user@host '[ "$(ls -A /empty/dir/* 2>/dev/null)" ] && echo "1" || echo "0"'
如果目录为空或不存在,则正确返回“0”。仅当目录包含某些内容时,它才会返回“1”
当我将这一行放在perl脚本中时,就像这样:
#!/usr/bin/perl
print `ssh user\@host '[ "$(ls -A /empty/dir/* 2>/dev/null)" ] && echo "1" || echo "0"'`
无论我在那里输入什么,它都返回一个“1”,不管是否为空目录。我将env值与普通shell和perl脚本进行了比较,它们是相同的
有人知道为什么这个命令只在perl脚本中返回不同的结果吗
这两台机器都是AIX6.1,默认shell为KSH。反勾号中的文本在传递到操作系统之前被插入双引号中。跑
print qq`ssh user\@host '[ "$(ls -A /empty/dir/* 2>/dev/null)" ] && echo "1" || echo "0"'`
查看要传递给操作系统的字符串。我敢打赌你至少要逃过$
一种更安全、更理智的方法是先生成命令,然后在backticks中运行:
# q{...} does no interpolation
my $cmd = q{ssh user\@host '[ "$(ls -A /empty/dir/* 2>/dev/null)" ] && echo "1" || echo "0"'};
print `$cmd`;
Perl可能正在调用/bin/sh。您是否尝试过直接调用ksh,
/bin/ksh ssh user…
?我已经尝试过了。我得到错误“ksh:test:0403-021 A]字符丢失”。无论我指定bash还是ksh。命令的$(…)
部分应该在远程主机上运行。本地主机是否使用sh或ksh并不重要。谢谢。你是对的,在使用“qq”之后,我可以看到它实际上被发送到了操作系统:“[“0 11 10 8 7 3 2 0ls-A/empty/dir*2>/dev/null)”。你能解释一下q{}是什么使它更安全吗?就像一个带引号的字符串一样,q{…}
不会插入它的内容。看见
use Net::SFTP::Foreign;
my $s = Net::SFTP::Foreign->new('user@host');
my $empty = 1;
if (my $d = $s->opendir('/empty/dir')) {
if (defined $s->readdir($d)) {
$empty = 0
}
}