3

リモートマシン上の空のディレクトリをチェックする必要があるperlスクリプトがあります。kshを使用すると、次のシェルスクリプトを機能させることができます。

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」、空のディレクトリを返します。通常のシェルとperlスクリプトと比較してenv値を確認しましたが、それらは同じです。

このコマンドがperlスクリプトでのみ異なる結果を返す理由を誰かが知っていますか?

どちらのマシンも、デフォルトのシェルとしてKSHを備えたAIX6.1です。

4

2 に答える 2

2

バッククォート内のテキストは、OSに渡される前に二重引用符で囲まれているかのように補間されます。走る

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

OSに渡される文字列を正確に確認します。私はあなたが少なくとも逃げなければならないだろうに違いない$

より安全で安全な方法は、最初にコマンドを作成し、後でバックティック内で実行することです。

# q{...} does no interpolation
my $cmd = q{ssh user\@host '[ "$(ls -A /empty/dir/* 2>/dev/null)" ] && echo "1" || echo "0"'};
print `$cmd`;
于 2012-11-30T16:21:43.820 に答える
0
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
  }
}
于 2012-12-01T16:33:07.713 に答える