1

I have a script which establishes connection to remote server using Perl module Net::OpenSSH and transfers files from local server to remote machine. This works perfectly fine.

...
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;
}

But whenever I execute this script I get message:

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

My understanding on line if ($ssh->system('mkdir', '-p', $remote_dir)) { is:

If $remote_dir doesn't exists create it recursively on remote machine.

But how the value of $ssh->system('mkdir', '-p', $remote_dir) becomes 1 even when directory already exists.

Maybe I am confused with -p flag. Experts comments expected. Thanks.

1 Answer 1

3

The -p flag doesn't care that the directory already exists. As long as it exists at the end, it exits successfully.

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

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

The man page for mkdir on macOS notes this behavior:

-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 returns true if the remote command exited successfully (exit 0, as you see above), so it will always return true if the directory exists at the end of the mkdir call.

This is a nice idempotent feature. You can run that mkdir -p as often as you like without worrying about the directories existing. You want that directory tree to exist and as long as it does, mkdir exits successfully.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.