Perl передача файлов на удаленный сервер с использованием Net :: OpenSSH - PullRequest
1 голос
/ 29 мая 2020

У меня есть сценарий, который устанавливает соединение с удаленным сервером с помощью Perl модуля Net::OpenSSH и передает файлы с локального сервера на удаленный компьютер. Это прекрасно работает.

...
my $ssh = ConnectToServer( $host, $user, $password );

my $remote_dir = "/home/shared/some/path/"

if ( $ssh->system('mkdir', '-p', $remote_dir) ) {
    print "Directory $remote_dir created!\n";
} else {
   print "Can't create $remote_dir on $host : ".$ssh->error."\n";
}

$ssh->scp_put({glob => 1}, "/home/shared/Test_Vinod/LOG/*.zip", $remote_dir)
        or die "scp failed: " . $ssh->error;

undef $ssh;

sub ConnectToServer {
    my ( $host, $user, $passwd ) = @_;
    my $ssh = Net::OpenSSH->new($host,
                                user => $user,
                                password => $passwd,
                                master_opts => [-o => "StrictHostKeyChecking=no"]
    );
    $ssh->error and die "Couldn't establish SSH connection: ". $ssh->error;

    return $ssh;
}

Но всякий раз, когда я выполняю этот скрипт, я получаю сообщение:

Directory /home/shared/some/path/ created!

Мое понимание в строке if ($ssh->system('mkdir', '-p', $remote_dir)) {:

If $remote_dir не существует, создайте его рекурсивно на удаленной машине.

Но как значение $ssh->system('mkdir', '-p', $remote_dir) становится 1, даже если каталог уже существует.

Может быть, меня сбивает с толку флаг -p. Комментарии экспертов ожидаются. Спасибо.

1 Ответ

3 голосов
/ 29 мая 2020

Флагу -p не важно, что каталог уже существует. Пока он существует в конце, он успешно завершается.

$ mkdir -p test/a/b/c
$ echo $?
0

$ mkdir -p test/a/b/c
$ echo $?
0

На странице руководства для mkdir в macOS отмечается такое поведение:

-p      Create intermediate directories as required.  If this
option is not specified, the full path prefix of each operand must
already exist. On the other hand, with this option specified, no
error will be reported if a directory given as an operand already
exists.  Intermediate directories are created with permission bits
of rwxrwxrwx (0777) as modified by the current umask, plus write
and search permission for the owner.

Net :: Openssl :: system возвращает истину, если удаленная команда завершилась успешно (выход 0, как вы видите выше), поэтому она всегда будет возвращать истину, если каталог существует в конце вызова mkdir.

Это хорошая идемпотентная особенность. Вы можете запускать этот mkdir -p так часто, как хотите, не беспокоясь о существующих каталогах. Вы хотите, чтобы это дерево каталогов существовало, и пока оно существует, mkdir успешно завершается.

...