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...
Re: scp file from windows10 to unix server
by haukex (Archbishop) 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', ...
| [reply] [d/l] [select] |
|
| [reply] [d/l] |
|
| [reply] |
Re: scp file from windows10 to unix server
by marto (Cardinal) 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?
| [reply] |
|
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...
| [reply] [d/l] |
Re: scp file from windows10 to unix server
by syphilis (Archbishop) 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 | [reply] [d/l] |
|
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 | [reply] [d/l] [select] |
|
| [reply] [d/l] [select] |
|
|
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...
| [reply] [d/l] |
|
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 | [reply] [d/l] [select] |
|
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.
| [reply] |
|
|
| [reply] [d/l] [select] |
Re: scp file from windows10 to unix server
by bliako (Monsignor) 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
| [reply] [d/l] [select] |
Re: scp file from windows10 to unix server
by kcott (Archbishop) on Feb 18, 2020 at 13:53 UTC
|
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.
| [reply] [d/l] [select] |
|
|