File Exchange

image thumbnail

SSH/SFTP/SCP For Matlab (v2)

version 1.10.1.1 (746 KB) by David Freedman
Improved Matlab interface for SSH2/SFTP/SCP (supports public key) using the Ganymed-SSH2 javalib.

82 Downloads

Updated 20 Aug 2018

View License

Editor's Note: This file was selected as MATLAB Central Pick of the Week

A new Matlab interface for using the Ganymed-SS2 Java library. Renamed commands are improved for limitations of existing Matlab/SSH2 codebase (see inspired submissions) using a straightforward command list.
If you need to access a remote machine from your Matlab session (for near-real time data transfer etc...) this set of functions allows you to send commands and obtain the return values. SFTP and SCP file transfer functions are included. Supports public key authentication and improved multiple command support.
This requires the open-source Ganymed SSH-2 for Java that is freely available and automatically included in the zip file. For SFTP-GET, one must use the included custom Ganymed SSH-2 Java library that is compatible with Matlab.

See ssh2-examples.m for documentation.

FOR SUPPORT, PLEASE CONTACT AUTHOR DIRECTLY instead of posting to "Comments and Ratings" first. Helpful information or comments can be posted after communication to ensure useful information for others instead of a ballooning of failed SSH/SFTP/SCP connection info in the comments.

#1 Problem with connections is software firewall on Matlab machine preventing Java from making connections. If you're able to connect with the same machine, please check for this.
#2 Problem is supported authentication on ssh-server. Please see the Ganymed-SSH2 faq for more information. http://www.ganymed.ethz.ch/ssh2/FAQ.html

Additionally, I would love to hear about how and where you're using this submission in the comments section.

Comments and Ratings (83)

Hi. First thank you for such a nice library!. I am trying to do X11 forwarding, Is it possible?

Jonas Grue

Great work!

Ori Perl

I sent an email but I am writing here to see if someone can help me sooner: I have "ls" working with the ssh, but I am trying to launch a ros node throuhg ssh with no success. Anyone have suggestions on how to achieve this?

David, thank you for sharing this very helpful toolbox. Have you developed the equivalents of rename and delete ?
Thanks in advance

Code works, but have you heard of classes/objects? half your code is checking that structs have fields - that's what classes do for you.

Le Yang

Ilkoo Ahn

Thank you for your sharing this wonderful code.
I would like to make a proposal.
I have coded the following to specify the port:
ssh2_conn = ssh2_config('sftp.thishost.com','username','password','1234');
However, this code produced an error. Later I found that I had to enter the port as an integer rather than text (as shown below).
ssh2_conn = ssh2_config('sftp.thishost.com','username','password',1234);
Please add an example to ssh2_examples.m for entering the port as an integer.
Thanks.

Il Gu Ahn

Thank you for your sharing this wonderful code.
I would like to make a proposal.
I have coded the following to specify the port:
ssh2_conn = ssh2_config('sftp.thishost.com','username','password','1234');
However, this code produced an error. Later I found that I had to enter the port as an integer rather than text (as shown below).
ssh2_conn = ssh2_config('sftp.thishost.com','username','password',1234);
Please add an example to ssh2_examples.m for entering the port as an integer.
Thanks.

Jiahe Pan

update:
the 'monitor' problem solved. It's due to different shell environment, solved by using absolute path. Use 2>&1 after commands to see stderr output.
And as the 'cd ..' problem, 'cd .. && ls -l' output the expected result. still have no clue right now.

Jiahe Pan

Hi David,
Thank you for your code. However, I have encountered some problem when using.
I have successfully build the connection and executed some commands, while some certain commands failed to function. The output is like:

>> ssh2_conn = ssh2_command(ssh2_conn,'pwd',1);
/root
>> ssh2_conn = ssh2_command(ssh2_conn,'cd ..',1);

>> ssh2_conn = ssh2_command(ssh2_conn,'pwd',1);
/root

(the 'cd ..' fails to change directory)

and neither could 'monitor' commands work (I'm using ssh to communicate with FPGA)

Besides, it seems like error infos will not be stored or printed.

Do you have any idea on this issue? Thank you very much.

David Young

Note for public key authentication (ssh2_config_publickey): The ssh2 key (RSA or DSA) generated by Putty or MobaXterm must be converted into openssh format to be recognised by ganimed ssh2 libraries.

Vlad Dascau

Thanks Sebastian, will try your solution.

@Vlad: I just saw your comment. Actually first I solved the problem by setting an empty password for the user I would like to use. Then the code snippet in my last post actually worked. But this is not a real solution since it might not be possible every time to set a user password, even when its empty.

To log in to a user that has no password set at all, I changed the file ssh2_main.m such that another Java method is called for authentication: In the section "%% AUTHENTICAE (PASSWORD OR PRIVATE KEY)" the script tries different authentication methods which are available in the Java library. The last method which is tried is to authenticate with username and password using the "ssh2_struct.connection.authenticateWithPassword" Java method. I replaced this method with the Java method "ssh2_struct.connection.authenticateWithNone" and it worked for me.

Here the corresponding code snippet with the case "username + password" (commented out) and the case only "username":
% ssh2_struct.authenticated = ssh2_struct.connection.authenticateWithPassword(...
% ssh2_struct.username,ssh2_struct.password)
ssh2_struct.authenticated = ssh2_struct.connection.authenticateWithNone(...
ssh2_struct.username);

I hope this helps you.

Cheers,
Sebastian

Vlad Dascau

I am having the same issue. Tried to connect to a passwordless root user on a board and tried what Sebastian Fischer said ( ssh2_config(HOSTNAME, USERNAME, "") )but it still didn't work. Using another user that has a password works. Any ideas ?

Liang Zhao

Was looking for something exactly like this, thank you!

Thanks David for that great contribution and also for quick response to my message.
I stumbled over the same issue as M. Ertem, i.e. login into a account that does not have a password set. Actually it is very very simple. I just want to post the solution here that others can benefit as well in case they have the same issue:
ssh2_conn = ssh2_config(HOSTNAME, USERNAME, "")

M. C Ertem

Thank you David!!! (both for writing the code, and helping quickly this morning...)

NOTE: (at least on for a BeagleBone) ssh2_simple_command did not work for me with a blank password
I used an account that has a password and it worked like a charm... (All I needed to do was issue a
'touch goTrigger' to the shell from inside Matlab to start my data acq routine on the BeagleBone.)

Igor Guryev

Igor Guryev

I'm having trouble while using scp_get(), scp_simple_get() or scp() in 'get=1' mode. The Matlab just hangs up and I have to terminate it manually. The problem appears for a single or multiple files.
scp_put works perfect.

Jon Åge

Oren Shriki

Christopher Eirich, please contact me directly for help. Please don't post your connection problems in the Comments and Ratings.

Hey David,

I have a successful connection, but I cannot execute any commands. I receive this for a simple 'ls' inquiry:

Error using ssh2_main (line 320)
Java exception occurred:
java.io.IOException: The execute request failed.

at ch.ethz.ssh2.channel.ChannelManager.requestExecCommand(ChannelManager.java:707)

at ch.ethz.ssh2.Session.execCommand(Session.java:248)

Caused by: java.io.IOException: The server denied the request.

at ch.ethz.ssh2.channel.ChannelManager.waitForChannelSuccessOrFailure(ChannelManager.java:191)

at ch.ethz.ssh2.channel.ChannelManager.requestExecCommand(ChannelManager.java:703)

... 1 more

Error in ssh2 (line 84)
ssh2_struct = ssh2_main(ssh2_struct);

Error in ssh2_command (line 31)
ssh2_struct = ssh2(ssh2_struct);

Error in ************************ (line 3)
ssh2_command(test, 'ls -l');

Yi Sui

Hi Massimo, You can use this tool as a way to build the functionality you're speaking about. But you will need to develop the logic on what files to replace. I would suggest using SSH to get list of files and their dates, processing that to determine what files to upload using SFTP or SCP. TL;DR it's possible but you'll have to do most of the heavy lifting.

Hello David,
thank you very much for providing such set of files. I am trying to use it and replace the need to use some linux scripts to perform transfer of files from a local server to a remote server. I would like to transfer files and possibly update the files stored in the destination folder doing a check of whether the destination is newer or not. Can this be done? I tried to implement cp or rsync calls using the matlab file "ssh2_command.m" but with no luck.
Please let me know if you can help me. Best, Massimo.

branch331

Mathworks should incorporate this in their next build!!!

Firman

Great library. In order to support Java libraries installed in other than current folder, one need to edit the file ssh2_setup.m.

Lines 114-121 in ssh2_setup.m needs to be changed to the following.

if (USE_CUSTOM_GANYMED_LIB > 0)
if exist('ganymed-ssh2-m1','dir')
ganymed_java_library = fileparts(which('ganymed-ssh2-m1.jar'));
else
ganymed_java_library = 'ganymed-ssh2-m1'; %included custom ganymed library
end
ganymed_java_library_zip = [ganymed_java_library '.zip'];
ganymed_java_library_http = '';
else
% PICK EITHER CLEONDRIS or GOOGLECODE, NOT BOTH
% FROM CLEONDRIS
if exist('ganymed-ssh2-build250','dir')
ganymed_java_library = fileparts(which('ganymed-ssh2-build250'));
else
ganymed_java_library = 'ganymed-ssh2-build250'; %included custom ganymed library
end

Great submission. David was also extremely helpful!

Mario

This is a great package that allows SFTP communication with Matlab.

In the beginning I had troubles using the sftp_get function, but after David's prompt feedback I managed to make it.
In my case, in order to get it working I needed to change line 107 on ssh2_setup.m:

USE_CUSTOM_GANYMED_LIB = 0;
to
USE_CUSTOM_GANYMED_LIB = 1;

and re-start Matlab.

Thanks, Mario.

changyu

Martin

Hi! This is super useful and a great library.

However, when I use the library on Mac and try to do uigetdir in matlab while the ssh library is loaded i get an interesting java exception. Is anyone else having this problem? Is there a workaround? Thanks, Martin

This is wonderful! Saves so much time!

I was wondering, however, if there was a way to download only snippets of FTP data. In other words, say that every day a file on FTP is updated. How can I download just the update and append it to a file I have on my computer instead of downloading ALL the past data, and the recent data on 1 file?

David, is there a way to add a timeout to ssh2_command that releases the session in case the process on the host computer hangs?

Best & tks for your good work!

PLEASE, please, PLEASE DO NOT post errors into the comments section.

RB

David, I have downloaded all the files correctly and want to send a file through sftp.

These lines execute correctly
ssh2_conn = ssh2_config(HOSTNAME,USERNAME,PASSWORD);
ssh2_struct = ssh2_config(HOSTNAME,USERNAME,PASSWORD);
ssh2_struct = sftp(ssh2_struct);

There is an error when I try to execute this -
ssh2_struct = ssh2_command(ssh2_struct,'ls');

Error using ssh2_main (line 320)
Java exception occurred:
java.io.IOException: The execute request failed.

at ch.ethz.ssh2.channel.ChannelManager.requestExecCommand(ChannelManager.java:707)

at ch.ethz.ssh2.Session.execCommand(Session.java:248)

Caused by: java.io.IOException: The server denied the request.

at ch.ethz.ssh2.channel.ChannelManager.waitForChannelSuccessOrFailure(ChannelManager.java:191)

at ch.ethz.ssh2.channel.ChannelManager.requestExecCommand(ChannelManager.java:703)

... 1 more

Error in ssh2 (line 84)
ssh2_struct = ssh2_main(ssh2_struct);

Error in ssh2_command (line 31)
ssh2_struct = ssh2(ssh2_struct);

I used this files to start a simulation in Ubuntu from Matlab installed on a Windows machine. As a command, I send './file_name_of_the_script' so that this script will be executed in Ubuntu. Important is to use the bash interpreter, not the shell (So the first line is then "#! /bin/bash")
Important is that the script file first loads all the needed environment variables. This can be done by using the source"-command. After this was done, I didn't had any troubles anymore running my simulations.
Thanks again David for your help!

When I uploaded a file using SFTP, the public read settings were off by default. This stopped me being able to view the file using a web browser.

David helped me to overcome this problem by explicityly setting the remote_file_mode. It worked like a charm. For example:

ssh2_conn = ssh2_config(hostname,username,password)
ssh2_conn.remote_file_mode = 0644
ssh2_conn = scp_put(ssh2_conn,test.html','www_folder','local_folder','new_name.html')
ssh2_conn=ssh2_close(ssh2_conn)

Solid, well documented package. Author responded very quickly to a query. Highly recommended.

Also, Ganymed .jars are available on Maven: http://mvnrepository.com/artifact/ch.ethz.ganymed/ganymed-ssh2/

Can you migrate the submission to github so that I could fork it and include in my "Matlab API for WRDS" project?

Hi Saugat, I don't respond to comments for technical help, for support you should contact me directly.

Saugat

Hello David,

I am getting the following error:

Error using ssh2_main (line 86)
Error: SSH2 could not connect to the ssh2 host - "localhost:8022"!

Error in ssh2 (line 84)
ssh2_struct = ssh2_main(ssh2_struct);

Error in scp (line 19)
ssh2_struct = ssh2(ssh2_struct);

Error in scp_put (line 57)
ssh2_struct = scp(ssh2_struct);

Error in scp_simple_put (line 55)
ssh2_struct = scp_put(ssh2_struct, localFilename, remotePath, localPath, remoteFilename);

Peat

David's submission provided SSH functionality I desperately needed to solve some problems. It was a lifesaver.

I ran into problems connecting my Windows client to the server running on a Mac. I eventually solved the problems by using the public private key mechanism for authentication. I also had to generate the key pair on the Mac and bring the private key across to the Windows machine to get everything to work.

Hatsue was able to figure out things working by doing this:
With administrator help, Enable password authentication. E.g., in case of OpenSSH on Fedora, edit /etc/sshd/sshd_config and change the value of "PasswordAuthentication" to "yes", then send a HUP signal to the daemon so that it re-reads its configuration.

Hatsue

I downloaded it to use on Linux CentOS and at first, I had some problems but David has supported me all the time. Now it greatly works! Thanks a lot to kind David!

error fixed!
I was missing the javaaddpath command!

Thank you so much for this wonderful submission!!

Hey David,

When I try to connect, I get the following error in Matlab command window -

Downloading ganymed-ssh2-build250.zip
From http://www.cleondris.ch/ssh2/ganymed-ssh2-build250.zip
Error using urlreadwrite (line 93)
The server did not find a resource to match this request.

Error in urlwrite (line 38)
[f,status] = urlreadwrite(mfilename,catchErrors,url,filename,varargin{:});

Error in ssh2_setup (line 233)
urlwrite(ganymed_java_library_http, ganymed_java_library_zip);

Error in ssh2_config_publickey (line 26)
ssh2_struct = ssh2_setup(); %default config

I'd really appreciate if you could help me with this!

Regards,
Tejas

M

Hi Enno,

Unfortunately, support for preserving date & time stamps is not part of the Ganymed SSH2 library that's used for SCP. The only alternative that I see would be to capture the date and time by SSH in first and then changing that on the downloaded files after the fact.

Enno

Hi David,

Your tooling all works like a charm, but is there a way to preserve date & time stamps when getting files from remote?
SCP man page states a -p option should do that trick, but I cannot figure out how to use that in the ssh matlab scripts.

Best regards,
Enno

Hi Chris, my pleasure.

Unfortunately, there's no direct support for using the wildcard "*" when using scp or sftp. I suggest using ssh to collect a list of files using the wildcard and then downloading the parsed list with scp or sftp.

Christopher

Thank you so much for the code. It's awesome.
By the way is there a way to use wild character for scp?

When I tried * for scp, it created a file named '*'

Package looks great; however, I get the following errors:
Error: SSH2 could not connect to the ssh2 host - "cosine"!

Error in ==> ssh2 at 84
ssh2_struct = ssh2_main(ssh2_struct);

Error in ==> ssh2_command at 31
ssh2_struct = ssh2(ssh2_struct);

Error in ==> ssh2_simple_command at 38
ssh2_struct = ssh2_command(ssh2_struct, command, enableprint);

However, I *am* able to connect with the system() command. Any thoughts?

Xiangrui Li

Great tool! The upload and download speed is much faster than some ftp client.

M

This package is great - well documented, easy to use, reliable! FYI, if you want to use it in a compiled MATLAB program, remove the calls to JAVAADDPATH within the ssh2_setup.m file as they will cause function errors and clear your global variables. Instead, add the path where the ganymed folder exists or will be downloaded (the current path of your program at the time) to the matlabroot/toolbox/local/classpath.txt file.

Madhuresh

While I'm in touch with the developer regarding my problem with this function, I do appreciate his quick response to my query.

Daniel Sica

Hi David,

Thanks very much for your help!
I'll check the FAQ.

For support, PLEASE CONTACT AUTHOR DIRECTLY.

Hi Daniel,

The issue stems from the fact you are not getting a bash (or tcsh) shell, and are therefore not getting any of the typical variables. Also, you cannot run a bash shell in interactive mode with this software.

This was a problem for me too, and I had to create a file that "exports" the variables, and after I log in, I include a "source" command before I issue any statements.

You may want to check the ganymed-ssh2 FAQ at http://www.cleondris.ch/opensource/ssh2/FAQ.html for more info.

Daniel Sica

This package is amazing!

I'm trying to execute a command in a personal server, but i'm having a problem.
I can execute a command like "cd /home/;ls -la;", but i can't "cd /home/;mpiexec -n np program". This last command is right when I do in the server shell.
Can you help me?

Hi Mit Dir, I would suggest sending the command with a forking modifier modifier, i.e. &, after the command. Hopefully, you don't need to wait for the command to finish, but if you do, hopefully you can check for a file to be written. Alternatively, you can hack something together like I did, where I run a script on the server that outputs a file when it's done. I have a loop that checks for that file, but in the meantime, you can run other things (local or remote).

Mit Dir

Hi David, thanks for a great package. I am playing with the functionality for your programm and have therefore one question.
When I send a command to an external server to start a modell calculation, matlab is suppressed into a "busy" modus and waits for the answer of the server. Is there any option avpoid this issue? Many thanks in advance.

Alberto

Very nice package. I was looking for this las couple of years. Now I am able to copy the data files from remote servers and analyze then automatically into matlab. Very nice!!!! Thanks a lot.

Very good package. After the last modifications, it also deals smoothly with sftp only servers. I highly appreciated the support of David Freedman
and its commitment at improving the software.

Wow, works perfectly! I'm using matlab to design masks for lithography. Now I don't have to constantly upload the files manually!

Thanks Jon, Nitay, and Danilo. I've updated the files to include Danilo's fix.

Nitay and Danilo are correct. I just upgraded to R2012a and now my previous fix doesn't work whereas it did on R2008b.

Danilo's fix should work for all cases...

"for jcp_index = 1:size(jcp,2)" does not work here. Just replace by "for jcp_index = 1:length(jcp)". Problem solved.

I'm sorry but this fix caused the config function to miss finding the jar file in the jcp (Maybe it's a matlab version issue?)

One of the functions in this package has an error:
ssh2_setup.m
line 217:
for jcp_index = 1:size(jcp,1)

should be:
for jcp_index = 1:size(jcp,2)

Updates

1.10.1.1

Updated Description removing the comments about non-custom ganymed library.

1.10.1.0

Per Mathworks requirements all .zip files have been removed. The default of using the custom ganymed-ssh2 library for SFTP-GET is now on.

1.10.0.0

Bug fix for SFTP-Put

1.9.0.0

Uploaded wrong file for r5 (didn't include SSH2 library)

1.8.0.0

Includes Ganymed-250 library as it can no longer be downloaded from http://www.cleondris.ch/

1.6.0.0

- BugFix: Added filename separator check for SFTP-GET which would error when downloading a unix filename.
- Made SFTP/SCP filename lists works as 1XN or NX1 arrays.

1.3.0.0

Created a custom Ganymed SSH-2 Java library (now included in attachment) that is compatible with the way Matlab handles Java byte arrays. This is needed to support SFTP-GET functionality. Default behavior still uses official Ganymed library.

1.2.0.0

Made change to ssh2_config.m to account for Matlab's array size version dependence of the dynamic java classpath.

1.1.0.0

Bug fix that Jon Douglass identified. correct check for java library being loaded.

MATLAB Release Compatibility
Created with R2009b
Compatible with any release
Platform Compatibility
Windows macOS Linux