Skip to content

How to execute shell command using SFTP channel in JSch?

I am trying to list all *.xml files in the directory. I do a cd first and then was trying to execute:

find . -type f -name *.xml

But not sure how exactly to do it. There were some example around the Exec channel but is there a way to do the find with SFTP itself?

String username = "abcd";
String password = "pqrst";
String host = "xxxxxx.xxxx.xxx";
int port = 22;
String SFTPWORKINGDIR  = "/xxx/xxx/xxx/xxxx";

Session     session     = null;
ChannelSftp channelSftp = null;
   
try {
    JSch jSch = new JSch();
    session = jSch.getSession(username, host, port);
    session.setConfig("StrictHostKeyChecking", "no");
    session.connect();
    channelSftp = (ChannelSftp) session.openChannel("sftp");
    channelSftp.connect();
    channelSftp.cd(SFTPWORKINGDIR);
    
    // List all the *xml file.
    // --------- Want to execute 'find . -type f -name "*.xml" ' here ---------
    
    /*  Vector fileList = channelSftp.ls() 
    
    for(int i=0; i<fileList.size();i++){
        LsEntry entry = (LsEntry) fileList.get(i);
        System.out.println(entry.getFilename());
    }*/
    
} catch (JSchException | SftpException e) {
    e.printStackTrace();
}
finally {
    if(session != null) session.disconnect();
    if(channelSftp != null) channelSftp.disconnect();
}

Answer

Your requirements are conflicting.

You cannot execute shell commands with SFTP.
(That’s true in any case, no matter what language or library are you using).


So you have to choose.

  • Either run your find shell command with “Exec channel”.
  • Or use a pure SFTP interface via ChannelSftp.ls (and programatically recurse into subdirectories). This approach is a way more laborious and will be magnitudes slower. On the other hand it will be a way more robust. And it is actually the only solution, if you do not have a shell access in the first place. Not to mention that it is platform-independent (what find command is not).