期間をハードコーディングせずに Perl 処理を一時停止するにはどうすればよいですか?
質問
次のコード スニペットを含む 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 を実行する権限が与えられています。
解決
あなた* .VBSファイル内のコードを確認してください。 system
機能は実行を続行する前に終了するの子プロセスを待ちます。あなた* .VBSファイルがFTPを実行するバックグラウンドタスクをフォークし、すぐに戻っているように見えます。
他のヒント
完璧な世界では、あなたのスクリプトは、ネット:: SFTPを使用するようにリライトされます::外国とアーカイブ::抽出する ..
道の醜いクイックハックの種類は、あなたの最初のシステムコールの前にタッチファイルを作成し、それが完了したら、ファイルを削除するか、SFTPフェッチスクリプトを変更し、しばらく持っているかもしれないようなので、
while(-e 'touch.file') {
sleep 5;
}
# foreach [...]
もちろん、あなたはあなたの.vbsファイル失敗し、削除を取り消すtouchfileや他の多くの悪い副作用を離れた場合世話をする必要があります。これは、迅速な解決(他のいずれの方法でも動作しない場合)は、()を呼び出します。システムなしに書き換えるまでにお時間を頂くまで、
のためになりますSFTP 転送が完了するまで Perl が待機する方法が必要ですが、スクリプトが現在作成されているため、Perl にはこれを知る方法がありません。(少なくとも 2 つのスクリプト言語と (GUI?) SFTP クライアントを組み合わせているようです。これは機能する可能性がありますが、正確に信頼性や堅牢性があるわけではありません。SFTP 転送を開始するのになぜ VBscript を使用するのでしょうか?)
4 つの選択肢が考えられます。
- Perl スクリプトは、CPAN のようなものを使用して、SFTP 転送自体を行うことができます。 ネット::SFTP ステータスを追跡できない外部ジョブを生成するのではなく、モジュールを生成します。
- Perl スクリプトは、コマンドライン SFTP ユーティリティ (次のような) を生成する可能性があります。 PSFTP)転送が完了するまで戻りません。
- または、転送が完了するまで戻らないように exec_SFTP.vbs スクリプトを変更します。
- 現在グラフィカル SFTP クライアントを使用していて、何らかの理由で切り替えることができない場合は、次のようなスクリプト言語を使用することをお勧めします。 AutoIt Perlの代わりに。AutoIt には、ウィンドウの状態が変わるのを待つ機能などがあるため、アクティビティの完了をより簡単に監視できます。
オプション 1 または 2 が最も堅牢で信頼性が高くなります。
私が提案することができる最高のは、ファイル転送が完了した後にのみ終了するexec_SFTP.vbsを変更しています。 system
は、それが完了すると呼ばれるプログラムを待ってそれはあなたの問題を解決する必要がありますのでます:
system LIST system PROGRAM LIST Does exactly the same thing as "exec LIST", except that a fork is done first, and the parent process waits for the child process to complete.
、あなたがサブプロセスの作成を追跡することができるかもしれません。あなたがサブプロセスのIDを取得する場合は、VBSの多様な子孫が終了したときに、それによって知っているそれらを監視することができます。
のWin32 ::プロセス::情報の実行中のプロセスからサブプロセスIDを取得することができます。
=多分これはばかな質問ですが、なぜ単に<のhref =「http://search.cpan.org/~drolsky/Net-SFTP-0.08/lib/Net/SFTP.pm」のrelを使用しません"nofollowをnoreferrer">ネット:: SFTPはとアーカイブ:: の抽出しますファイルをダウンロードし、解凍するにはPerlのモジュール?
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);
<のhref = "http://search.cpan.org/~rjbs/perl-5.16.1/ext/IPC-Open3/lib/IPC/Open3.pm" のrel = "nofollowをnoreferrerを見てください「> IPC ::のopen3する
IPC ::のopen3 - のopen3を使用して処理する読み取り、書き込み、およびエラーのために開く工程()