1

このコード スニペットを含む Perl スクリプトがあります。これは、システム シェルを呼び出して SFTP でいくつかのファイルを取得し、WinZip で解凍します。

#  Run script to get files from remote server
system "exec_SFTP.vbs";

#  Unzip any files that were retrieved
foreach $zipFile (<*.zip>) {
    system "wzunzip $zipFile";
}

一部のファイルが取得されたとしても、ファイルが取得されて SFTP 接続が閉じられるまでに、Perl スクリプトは既に解凍ステップを完了しており、解凍するものが見つからないため、それらのファイルは決して解凍されません。

私の短期的な修正は、挿入することです

sleep(60);

ただし、これは SFTP 接続が 60 秒以内に終了することを前提としているため、大幅に過大評価されることもあれば、過小評価されることもあります。

解凍ステップに進む前に、SFTP 接続が閉じられるまで Perl を一時停止させるより適切な方法はありますか?

編集: レスポンダーは、Perl にファイル転送を行わせるのではなく、VB スクリプトを使用することに疑問を呈しました (そして当然のことながら)。これはセキュリティに関係しています。VB スクリプトは他の人によって管理されており、SFTP を実行する権限があります。

4

8 に答える 8

12

*.vbs ファイルのコードを確認してください。このsystem関数は、子プロセスが終了するのを待ってから実行を続けます。*.vbs ファイルがバックグラウンド タスクをフォークして FTP を実行し、すぐに戻っているようです。

于 2009-05-19T19:54:27.230 に答える
6

完璧な世界では、スクリプトはNet::SFTP::ForeignおよびArchive::Extractを使用するように書き直されます。

最初のシステムコールの前に touch-file を作成し、sftp-fetching スクリプトを変更してファイルを削除し、そのようにしてしばらく待つという、醜いクイックハックのような方法があります。

while(-e 'touch.file') {
    sleep 5;
}

# foreach [...]

もちろん、.vbs が失敗して touchfile が削除されないままになったり、その他の多くの悪影響が生じたりする場合は注意が必要です。これは、system() 呼び出しなしで書き直す時間が得られるまで、(他の提案がどれもうまくいかない場合) 迅速な解決策になります。

于 2009-05-19T20:16:51.677 に答える
4

SFTP 転送が完了するまで Perl が待機する方法が必要ですが、現在スクリプトが作成されているため、Perl にはこれを知る方法がありません。(少なくとも 2 つのスクリプト言語と (GUI?) SFTP クライアントを組み合わせているようです。これは機能しますが、信頼性や堅牢性に欠けます。なぜ VBscript を使用して SFTP 転送を開始するのですか?)

次の 4 つのオプションが考えられます。

  1. Perl スクリプトは、ステータスを追跡できない外部ジョブを生成するのではなく、 CPAN のNet::SFTPモジュールのようなものを使用して、SFTP 転送自体を実行できます。
  2. Perl スクリプトは、転送が完了するまで戻らない コマンドライン SFTP ユーティリティ ( PSFTP など) を生成する可能性があります。
  3. または、exec_SFTP.vbs スクリプトを変更して、転送が完了するまで戻らないようにします。
  4. 現在グラフィカルな SFTP クライアントを使用していて、何らかの理由で切り替えることができない場合は、Perl の代わりにAutoItなどのスクリプト言語を使用することをお勧めします。AutoIt には、ウィンドウの状態が変化するのを待つ機能などがあるため、アクティビティの完了をより簡単に監視できます。

オプション 1 または 2 が最も堅牢で信頼性が高くなります。

于 2009-05-19T19:54:34.733 に答える
3

私が提案できる最善の方法は、ファイル転送が完了した後にのみ終了するように exec_SFTP.vbs を変更することです。 system 呼び出したプログラムが完了するのを待つので、問題は解決するはずです。

       システムリスト
       システムプログラム一覧
               「exec LIST」とまったく同じことを行いますが、次の点を除きます。
               フォークが最初に行われ、親プロセス
               子プロセスが完了するのを待ちます
于 2009-05-19T19:56:29.143 に答える
1

ばかげた質問かもしれませんが、Net::SFTPおよびArchive::Extract Perl モジュールを使用してファイルをダウンロードおよび解凍しないのはなぜですか?

于 2009-05-19T20:03:12.937 に答える
0

IPC::Open3を見てください。

IPC::Open3 - open3() を使用して、読み取り、書き込み、およびエラー処理のためのプロセスを開く

于 2009-05-19T19:52:05.080 に答える
0

systemコマンドを実行しているシェルが戻るまで戻りません。これは、グラフィカル プログラムやファイルの関連付けを起動する場合に間違っている可能性があります。

次のいずれかが役立つかどうかを確認してください。

system('cscript exec_SFTP.vbs');

use Win32::Process;
use Win32;
Win32::Process::Create(my $proc, 'wscript.exe',
        'wscript exec_SFTP.vbs', 0, NORMAL_PRIORITY_CLASS, '.');
$proc->Wait(INFINITE);
于 2009-05-19T20:00:10.273 に答える