我想通过我的java程序从ssh执行多个命令。基于执行结果,我需要在同一个shell上执行更多命令。但是当我试图执行它时,它采取了不同的shell。如果有人知道分辨率非常受欢迎。
这是我的代码段
public class sshconnectionTest {
JSch jsch = new JSch();
Session session;
Channel channel;
public Session openSession() throws Exception {
if (null == session) {
session = jsch.getSession("user", "hostname",
22);
System.out.println("**************************************"
+ session.isConnected());
AESencrp aesEncrypt = new AESencrp();
session.setPassword("pwd");
session.setConfig("StrictHostKeyChecking", "no");
session.connect(10 * 1000);
}
return session;
}
public Channel openChannel(Session session) throws Exception {
if (null == channel) {
channel = session.openChannel("exec");
}
return channel;
}
public String getSession(String command1) throws Exception {
try {
session = openSession();
channel = openChannel(session);
Channel channel = session.openChannel("exec");
((ChannelExec) channel).setCommand(command1);
channel.setInputStream(null);
((ChannelExec) channel).setErrStream(System.err);
InputStream in = channel.getInputStream();
channel.connect();
byte[] tmp = new byte[1024];
String readText = "";
while (true) {
while (in.available() > 0) {
int i = in.read(tmp, 0, 1024);
if (i < 0)
break;
readText = new String(tmp, 0, i);
System.out.print(readText);
}
if (channel.isClosed()) {
System.out.println("exit-status: "
+ channel.getExitStatus());
break;
}
try {
Thread.sleep(1000);
} catch (Exception ee) {
}
}
channel.disconnect();
// session.disconnect();
System.out.println("DONE");
} catch (Throwable t) {
System.out.println(t);
}
return null;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
sshconnectionTest sshcon = new sshconnectionTest();
String command1 = " env | grep CCM;";
String session = sshcon.getSession(command1);
String command = "export SRL_FILE=/home/20140224/myfile.txt;";
sshcon.getSession(command);
sshcon.getSession("env | grep SRL;");
sshcon.getSession("pwd");
} catch (Exception e) {
}
}
}
`
答案 0 :(得分:1)
每次拨打getSession()
时,您都会收到新会话。这就是为什么每个命令都在不同的shell中执行的原因,因为它是一个不同的shell。
相反,在main()
中进行一次会话,保留该对象。然后重复使用它。
除了getSession()
之外,你需要一个不同的方法,更不用说“get session”对于在远程shell上执行命令的方法来说不是一个好名字...即。这不只是一个会议,而是做其他事情。这违反了最不惊讶的原则,即。每种方法都应该只做一件事。
创建一个新方法,称为:executeRemoteCommand(String command)
并使用它来执行命令。您可以使用getSession()
一次,并将会话存储在可从每个方法访问的对象中,即。实例变量。或者您可以将会话传递到executeRemoteCommand()
方法。就像:executeRemoteCommand(Session session, String command)
。
这是我过去如何做到这一点的一个例子(不会假装这个代码是完美的......但它应该给你一些想法)。这用于通过sFTP从linux服务器发送和接收文件。通过一些修改,它可以将任何命令发送到您想要的远程shell。
package com.somecompany.productfeed;
import net.snakedoc.jutils.ConfigException;
import org.apache.log4j.Logger;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpException;
public class SFTP {
// setup logger
private static final Logger LOG = Logger.getLogger(SFTP.class.getName());
private JSch jsch;
private ChannelSftp sftpChannel;
private Session session;
private String username;
private String password;
private String host;
private int port;
// singleton
private volatile static SFTP instance = null;
/**
* Private constructor used in Singleton pattern.
* All variables populated via properties file upon
* object instantiation. Since we only need FTP to one server,
* object variables are immutable after instantiation.
*
* @throws ConfigException
* @throws NumberFormatException
*/
private SFTP() throws ConfigException, NumberFormatException {
this.jsch = new JSch();
this.username = Config.getInstance().getConfig("SFTP_USER");
this.password = Config.getInstance().getConfig("SFTP_PASS");
this.host = Config.getInstance().getConfig("SFTP_HOST");
this.port = Integer.parseInt(Config.getInstance().getConfig("SFTP_PORT"));
}
/**
* Create or Return SFTP Object using Singleton pattern.
*
* @return Singleton of SFTP Object.
* @throws NumberFormatException
* @throws ConfigException
*/
public static SFTP getInstance() throws NumberFormatException, ConfigException {
if (SFTP.instance == null) {
synchronized (SFTP.class) {
if (SFTP.instance == null) {
SFTP.instance = new SFTP();
}
}
}
return SFTP.instance;
}
/**
* If connection is not already open/connected, open connection.
*
* @throws JSchException
*/
public void openConnection() throws JSchException {
LOG.info("Opening SFTP Connection");
if (null == getSession() || ! getSession().isConnected()) {
setSession(jsch.getSession(this.username, this.host, this.port));
getSession().setConfig("StrictHostKeyChecking", "no");
getSession().setPassword(this.password);
getSession().connect();
Channel channel = getSession().openChannel("sftp");
channel.connect();
setSftpChannel((ChannelSftp) channel);
} else {
LOG.info("SFTP Connection already open");
}
LOG.debug("Success");
}
/**
* Closes connection.
*/
public void closeConnection() {
LOG.info("Closing SFTP connection");
getSftpChannel().exit();
getSession().disconnect();
LOG.debug("SFTP Connection closed");
}
/**
* Checks if SFTP Connection is open.
*
* @return TRUE if connection is open, FALSE if connection is closed
*/
public boolean isOpen() {
if (getSession().isConnected()) {
return true;
} else {
return false;
}
}
/**
* Gets SFTP Channel
*
* @return SFTP Channel (<code>ChannelSftp</code>)
*/
private ChannelSftp getSftpChannel() {
return this.sftpChannel;
}
/**
* Returns current <code>Session</code>
*
* @return <code>Session</code>
*/
private Session getSession() {
return this.session;
}
/**
* Sets SFTP Channel (<code>ChannelSftp</code>)
*
* @param sftpChannel Channel to set this object's <code>ChannelSftp</code>
*/
private void setSftpChannel(ChannelSftp sftpChannel) {
this.sftpChannel = sftpChannel;
}
/**
* Sets current <code>Session</code>
*
* @param session Sets this object's <code>Session</code>
*/
private void setSession(Session session) {
this.session = session;
}
/**
* Pushes local file to remote location
*
* @param local String representation of filepath + filename (ex: /some_local_directory/somefile.txt)
* @param remote String representation of filepath + filename (ex: /some_remote_directory/somefile.txt)
* @throws SftpException
*/
public void push(String local, String remote) throws SftpException {
LOG.info("Sending file: " + local + " to remote: " + remote);
getSftpChannel().put(local, remote);
LOG.debug("Success");
}
/**
* Gets remote file to local location
*
* @param remote String representation of filepath + filename (ex: /some_remote_directory/somefile.txt)
* @param local String representation of filepath + filename (ex: /some_local_directory/somefile.txt)
* @throws SftpException
*/
public void get(String remote, String local) throws SftpException {
LOG.info("Retrieving file: " + remote + " saving to: " + local);
getSftpChannel().get(remote, local);
LOG.debug("Success");
}
}