Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

scp file from windows10 to unix server

by vinoth.ree (Monsignor)
on Feb 18, 2020 at 12:01 UTC ( #11113093=perlquestion: print w/replies, xml ) Need Help??

vinoth.ree has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks,

I have been trying to use C:/Windows/System32/OpenSSH/scp.exe command to copy a file from windows10 to unix server. But I always get error,

system cannot find the path specified.

I have generated rsa key and copied into authorised_keys file at unix server. So no password required.

my $src_cmd = "C:/Windows/System32/OpenSSH/scp ". $src_file. " vinot +hg\@$server:".$target_path; print("Source copy cmd: $src_cmd\n"); my $output = qx($src_cmd); my $status = $? >> 8 ; if( $status ){ print("Error: $output\n"); return 0 }

It prints,

Source copy cmd: C:/Windows/System32/OpenSSH/scp D:/dev/eee/src/sample +.dat vinothg@ipaddress:/home/vinothg/src/20200218124538501.dat The system cannot find the path specified.

even I tried with sing backward slash(\) and double(\\)slash, but getting the same error. But when I copy and run the above command in windows cmd prompt it copies the files correctly without any issues.

I have been asked to use this scp command instead of installing perl modules.


All is well. I learn by answering your questions...

Replies are listed 'Best First'.
Re: scp file from windows10 to unix server
by haukex (Chancellor) on Feb 18, 2020 at 12:19 UTC

    Unfortunately, I don't have a system where I can test at the moment, but here are some things I'd try:

    • Split the command into a list, e.g. my @cmd = ('C:/Windows/System32/OpenSSH/scp', $src_file, 'vinothg@'.$server.':'.$target_path );
    • Use either IPC::System::Simple's capturex (comes preinstalled with Strawberry Perl), as in: use IPC::System::Simple qw/capturex/; my $output = capturex(@cmd);
    • Or, use Win32::ShellQuote's quote_system_string, as in: use Win32::ShellQuote qw/quote_system_string/; my $cmd = quote_system_string(@cmd); my $output = qx/$cmd/;
    • In terms of error handling, the only case that indicates success is when $? is zero, so you shouldn't be checking $status the way you are, you should be checking if ( $? != 0 ). Update: Note that an advantage of IPC::System::Simple is that it does the error handling for you.
    • Although I don't think this is the issue, try saying scp.exe instead of just scp. Also, do try backslashes in the command one more time, as in my @cmd = ('C:\\Windows\\System32\\OpenSSH\\scp.exe', ...
      Hi haukex

      Thanks for the quick answer, Mine is ActiveState perl very old version 5.8.8, So I do not have IPC::System::Simple and Win32::ShellQuote modules availble.

      /

      All is well. I learn by answering your questions...
Re: scp file from windows10 to unix server
by marto (Archbishop) on Feb 18, 2020 at 12:30 UTC

    As a side note to what has already been said, have you considered looking into Net::SFTP::Foreign?

      Hi marto,

      This is very useful, I used this module(just download and put into the perl site path) and completed the task.

      my $private_key = $ENV{'APPDATA'}."\\ssh_key\\putty_gen_private_key.pp +k"; $sftp = Net::SFTP::Foreign->new($server, user => $user, ssh_cmd => 'plink', more => [ -i => $private_key] ); $sftp->die_on_error("Unable to establish SFTP connection");

      used put() methed to copy the files from windows to unix.


      All is well. I learn by answering your questions...
Re: scp file from windows10 to unix server
by syphilis (Bishop) on Feb 18, 2020 at 12:39 UTC
    Just to confirm that I've struck similar issues (with various commands) over the years, and the first suggestion that haukex mentioned has worked, for reasons that I've never worked out.

    I think the problem is that either the source file or the destination (probably the latter) is not being found.
    If the scp executable was not being found you should instead get the following error:
    'C:/Windows/System32/OpenSSH/scp' is not recognized as an internal or +external command, operable program or batch file.
    Cheers,
    Rob
      Just to confirm that I've struck similar issues (with various commands) over the years, and the first suggestion that haukex mentioned has worked, for reasons that I've never worked out.

      The difference is: system($cmd) runs the command (with its contained arguments) via a shell which is spawn first, whereas the system($exename, @args) calls the $exename command directly without the mediation of any shell (unless of course it is a shell-interpreted script). In Unix, the shell will take care of wildcard expansion *.xyz and the interpretation of special variables, e.g. ~/. So, there is a difference in what finally is run. In windows I don't know if the shell does anything and what. I am sure that, in any OS, the added layer will have its effect on metacharacter quotation and escaping ...

      If there is only one scalar argument, the argument is checked for shell metacharacters, and if there are any, the entire argument is passed to the system's command shell for parsing (this is /bin/sh -c on Unix platforms, but varies on other platforms). If there are no shell metacharacters in the argument, it is split into words and passed directly to execvp , which is more efficient. On Windows, only the system PROGRAM LIST syntax will reliably avoid using the shell; system LIST , even with more than one element, will fall back to the shell if the first spawn fails.

      (from system manpage)

      edit: removed a section and placed it in separate comment

      bw, bliako

        whereas the system($exename, @args) calls the $exename command directly without the mediation of any shell

        On Windows, "The issue is not the shell."

      Hi syphilis

      I got not recognized as an internal or external command error when I use just scp.exe instead of absolute path,

      I think the problem is that either the source file or the destination (probably the latter) is not being found.

      But I am able to run it in cmd line without issues.


      All is well. I learn by answering your questions...
        I got not recognized as an internal or external command error when I use just scp.exe instead of absolute path,

        If you want to run the command as simply scp.exe or scp then you'll need to add C:/Windows/System32/OpenSSH to the PATH:
        set PATH=%PATH%;C:\Windows\System32\OpenSSH
        But I am able to run it in cmd line without issues

        Yes, I understand that.
        I'm just saying that when I've struck this type of issue in the past, the first approach that haukex suggested of replacing system($cmd) with system(@cmd) has often worked for me.
        That's the first thing I'd be trying.
        Oh ... and use warnings; if they're not already enabled.

        Cheers,
        Rob
        I think the problem is that either the source file or the destination (probably the latter) is not being found.

        You don't need to guess: As I said, better error handling in Perl will help, and also you can always try things at the command line and compare the errors you get: Try using the command line to copy a file that doesn't exist locally, and to a destination that causes an error.

      To confirm the same I removed the destination path and let the scp.exe to copy the file to my home directory as below,

      C:/Windows/System32/OpenSSH/scp.exe D:/dev/eee/src/sample.dat vinothg@ipaddress:

      But got the same error


      All is well. I learn by answering your questions...
Re: scp file from windows10 to unix server
by bliako (Parson) on Feb 18, 2020 at 18:06 UTC

    side-note to vinoth.ree: if the powers-to-be running your environment would not allow installing a battle-tested Perl module and turn its authors' free hardwork and dilligence to corporate profit, then they will surely freak out screaming if they see you calling an executable without its extension. Alas they probably have no idea and are just cargo-culting.

    Calling executables with no extension it's a feature turned into a huge security hole (attributions to the usual culprit). You call C:/Windows/System32/OpenSSH/scp but which one is it? scp.com, scp.exe, scp.bat, scp.cmd, scp.vbs? PATHEXT will tell you that and who knows who and what messed up with that already. (To be fair, Unix has already this problem with PATH, windows has it with both PATH and PATHEXT)

    Anyway, a suggestion for the problem at hand: perhaps create a batch file and insert your commands there and make sure that it runs OK. Then call the batch file from your perl script. If that works, then keep altering your quotes ...

    bw, bliako

Re: scp file from windows10 to unix server
by kcott (Bishop) on Feb 18, 2020 at 13:53 UTC

    G'day vinoth.ree,

    I have Windows 10. I have an oldish ActivePerl (5.16.3) but not as old as your 5.8.8. I also have:

    C:\Users\ken>dir C:\Windows\System32\OpenSSH\scp.exe ... 19-Mar-19 17:19 322,560 scp.exe ...

    Locally, I created D:\tmp\sample.dat: it just contains the string "This is sample data."

    Remotely, I checked for ~/tmp/sample.dat: not found.

    Locally, I ran (via cmd.exe):

    C:\Users\ken>perl -e "my $cmd = qq{C:\\Windows\\System32\\OpenSSH\\scp +.exe D:\\tmp\\sample.dat W\@X.Y.Z:/A/B/C/tmp/sample.dat}; qx{$cmd}" Password: C:\Users\ken>

    Remotely, I now have ~/tmp/sample.dat which just contains the string "This is sample data."

    Because the remote machine is a $work computer, I was somewhat loathe to publish details. You can probably work out: W is my username; X.Y.Z is the URL; and, /A/B/C/tmp is ~/tmp.

    Hopefully, if you use the same "\\", "\" and "/" combinations as I did, your scp will work.

    — Ken

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://11113093]
Approved by marto
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others scrutinizing the Monastery: (9)
As of 2020-04-01 09:06 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    To "Disagree to disagree" means to:









    Results (186 votes). Check out past polls.

    Notices?