2012-11-30 63 views
3

的shell命令我有一個需要檢查遠程計算機上的空目錄中的perl腳本。使用KSH我可以得到下面的shell腳本的工作:不同的結果與進出Perl腳本

ksh# ssh [email protected] '[ "$(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腳本返回不同的結果?

兩款機器AIX 6.1 KSH作爲默認的shell。就好像它是雙引號內傳遞到操作系統之前

+1

Perl是可能調用/ bin/sh的。你有沒有試過直接調用ksh,'/ bin/ksh ssh user ...'? – sidyll

+0

我試過了。我收到錯誤'ksh:test:0403-021 A]字符丟失。'不管我是否指定bash或ksh。 –

+0

該命令的'$(...)'部分應該在遠程主機上運行。本地主機使用sh還是ksh並不重要。 – mob

回答

2

內反引號的文本插入。運行

print qq`ssh user\@host '[ "$(ls -A /empty/dir/* 2>/dev/null)" ] && echo "1" || echo "0"'` 

確切地看到傳遞給操作系統的字符串。我敢打賭,你至少得逃過$

一個更安全和更理智的方法是先後建立自己的命令,並運行它內部的反引號:

# q{...} does no interpolation 
my $cmd = q{ssh user\@host '[ "$(ls -A /empty/dir/* 2>/dev/null)" ] && echo "1" || echo "0"'}; 
print `$cmd`; 
+0

謝謝。你是對的,在使用'QQ'後,我可以看到這實際上是發送到操作系統:'[「0 11 10 8 7 3 2 0ls -A/empty/dir * 2>/dev/null)」]' 。你能解釋一下q {}是什麼讓它更安全嗎? –

+0

與單引號字符串一樣,「q {...}」不插入其內容。請參閱[perlop中的[引用類運算符]](http://search.cpan.org/perldoc?perlop#Quote-Like_Operators)。 – mob

0
use Net::SFTP::Foreign; 

my $s = Net::SFTP::Foreign->new('[email protected]'); 
my $empty = 1; 
if (my $d = $s->opendir('/empty/dir')) { 
    if (defined $s->readdir($d)) { 
    $empty = 0 
    } 
}