rysnc_put并且scp_put都顯示終端中的進度。但是當我嘗試將其寫入檔案時,我只能從rysnc_put. 即使我只是列印來自 pty [我的編輯] 的輸出,問題仍然存在。這是我pty使用的問題嗎?僅提及,當不是scp_put時沒有進展。STDOUTtty
請注意,除非它的標準輸出流附加到 tty,否則 scp 不會生成進度報告。
#!/usr/bin/perl
use strict;
use warnings;
use Net::OpenSSH;
my $SSH = Net::OpenSSH->new(
'192.168.178.33',
(
user => 'TT',
password => 'TTpassword',
port => '22',
)
);
my $pty = new IO::Pty;
my $slave = $pty->slave;
$SSH->scp_put(
{
quiet => 0,
verbose => 1,
stdout_fh => $pty,
stderr_fh => $pty,
bwlimit => '200',
},
'/opt/TT/CHANGES.md',
'/opt/TT/CHANGES.md',,
);
while (<$pty>) {
print STDOUT "$_";
}
uj5u.com熱心網友回復:
您的問題的另一個解決方案是自定義Net::SSH::Any提供的 SCP 協議的純 perl 實作。
我將該包中的 SCP 類設計為子類,以便可以完成類似的事情,但從未真正記錄該 API,所以,好吧,您將依賴未記錄的功能(不過,我不打算更改它)。
use strict;
use warnings;
package MyPutter {
use parent 'Net::SSH::Any::SCP::Putter::Standard';
use Data::Dumper qw(Dumper);
for my $name (qw(open_dir open_file close_file close_dir)) {
my $method = $name;
my $super = Net::SSH::Any::SCP::Putter::Standard->can($name);
no strict 'refs';
*$name = sub {
my ($putter, $a) = @_;
print STDERR "$method $a->{path} --> $a->{local_path}\n";
$super->(@_);
};
}
sub read_file {
my $putter = shift;
my $a = shift;
my $data = $putter->SUPER::read_file($a, @_);
$a->{bytes_copied} = length($data);
print STDERR "read_file $a->{path} --> $a->{local_path} $a->{bytes_copied}/$a->{size}\n";
return $data;
}
};
use Net::OpenSSH;
my $ssh = Net::OpenSSH->new("localhost");
my $any = $ssh->any;
my $putter = MyPutter->_new($any, {}, "/tmp/out2", "/tmp/passwd3");
$putter->run({})
uj5u.com熱心網友回復:
即使scp_put和rsync_put是相似的方法,它們也包裝了兩個不相關的程式(scp和rsync),就此事而言,它們的行為方式不同。
具體來說,scp檢查它的 stdio 流是否附加到一個 pty,如果沒有,它會抑制進度訊息。AFAIK 無法禁用該功能。
更新:從 PTY 并行讀取:
此代碼從 PTY 讀取資料并將資料并行寫入檔案:
use strict;
use warnings;
use Net::OpenSSH;
use POSIX ();
use IO::Pty;
my $ssh = Net::OpenSSH->new("localhost"); #, scp_cmd => "/home/salva/t/openssh-8.9p1/scp");
my $pty = new IO::Pty;
my $slave = $pty->slave;
print "slave: $slave, fd: ".fileno($slave)."\n";
my $logger_pid = fork;
unless ($logger_pid) {
defined $logger_pid or die "fork failed: $!";
open my $log, ">", "/tmp/scp.log";
select $log;
$| = 1;
print("Reading from PTY\n");
while (1) {
my $buffer;
sysread($pty, $buffer, 1);
syswrite($log, $buffer, 1);
}
print "PTY closed unexpectedly\n";
POSIX::_exit();
}
my $scp_pid = fork;
unless($scp_pid) {
defined $scp_pid or die "fork failed: $!";
$pty->make_slave_controlling_terminal();
$ssh->scp_put({stdout_fh => $slave,
stderr_fh => $slave,
quiet => 0},
"/etc/passwd", "/tmp/foo.vdi");
}
waitpid($scp_pid, 0);
kill 9, $logger_pid;
waitpid($logger_pid, 0);
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/453017.html
