我试图在不接触它的10年后重新学习Java。我想从我想要编写的其他一些应用程序中使用JSch创建一个库。我有连接,但我现在正在使用stdin和stdout。 我希望有一个方法接受String中的单个命令,并返回带有结果的ArrayList。
任何帮助都会很棒!
//This vars are in the class.
private JSch _jsch;
private Session _session;
private Channel _channel;
这是我的连接方法
public boolean Connect () throws JSchException
{
try {
_jsch = new JSch();
_session = _jsch.getSession(_user, _hostname, _port);
_session.setPassword(_password);
_session.setConfig("StrictHostKeyChecking", "no");
_channel = _session.openChannel("shell");
//((ChannelShell)_channel).setPtyType("vt100");
_channel.setInputStream(bais);
_channel.setOutputStream(baos);
_channel.connect(3000);
}//try to connect
catch (JSchException ex)
{
throw ex;
}
return true;
}
目标是,一旦我打开连接,我就可以向该方法发送命令并将结果返回到数组中。根据结果执行并发送更多命令。我不想每次都关闭连接,因为它们将构建在它之前的命令上。我不知道如何使用输入和输出流足以获得我正在寻找的结果。如果您能协助填写以下方法,我将不胜感激。
public List<String> ExecuteCommand (String command) {
//run command to existing connection
//Get returned lines to Array List and return the list
}
谢谢
答案 0 :(得分:0)
这是一个运行本地流程并创建一个返回ArrayList
的示例,该流程与流程的输出一行一行地填充。虽然它不是你想要的,但它应该给你一个想法。
public List<String> ExecuteCommand (String command) {
Runtime r = Runtime.getRuntime();
Process p = r.exec(command);
p.waitFor();
BufferedReader b = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = "";
ArrayList<String> output = new ArrayList<String>();
while ((line = b.readLine()) != null) {
output.add(line);
}
return output;
}
答案 1 :(得分:0)
我创建了open source project (click to see)来实现远程文件系统。这是最重要的代码段,它也支持sudo
。在该示例中,我将错误输出重定向到标准输出。 如果您不想输出错误,可以将其删除。在示例中,我使用StringWriter而不是List&lt; String&gt;。我鼓励你使用它。
/**
* Executes commands at target host.
* @throws IOException Failed to capture a return code
*/
public int exec(boolean sudo, String command, StringWriter output) throws IOException {
ChannelExec channel = null;
try {
channel = (ChannelExec) session.openChannel("exec");
sudo = sudo && !username.equals("root");
if (sudo) {
command = "sudo -S -p '' " + command;
channel.setPty(true);
}
channel.setCommand(command);
InputStream stdout = channel.getInputStream(); // The stream will be recycled automatically
InputStream stderr = channel.getErrStream(); // The stream will be recycled automatically
channel.connect();
boolean passwordEntered = false;
if (sudo && !StringUtils.isEmpty(password)) {
OutputStream stdin = channel.getOutputStream();
stdin.write(password.getBytes());
stdin.write("\n".getBytes());
IOUtils.closeQuietly(stdin);
passwordEntered = true;
}
String contents = readFully(stdout);
if (passwordEntered) {
contents = contents.substring(password.length());
}
output.write(contents.trim());
contents = readFully(stderr);
int retval = channel.getExitStatus();
if (retval != 0) {
output.append(contents.trim());
}
return retval;
}
catch (JSchException ex) {
throw new IOException(ex);
}
finally {
output.flush();
if (channel != null) {
channel.disconnect();
}
}
}
private static String readFully(InputStream input) throws IOException {
StringBuilder output = new StringBuilder();
int bytesRead = input.read();
while (bytesRead != -1) {
output.append((char) bytesRead);
bytesRead = input.read();
}
return output.toString();
}
答案 2 :(得分:0)
这是我目前的解决方案。它可以使用一些流衬里和清理,但它正在让我得到我想要的东西。
我并不想将此标记为答案,但我还没有发布到此网站,如果我做错了,请原谅我。这是新的连接方法
public boolean Connect () throws JSchException
{
try {
_jsch = new JSch();
_session = _jsch.getSession(_user, _hostname, _port);
_session.setPassword(_password);
_session.setConfig("StrictHostKeyChecking", "no");
_session.connect();
_channel = _session.openChannel("shell");
_channel.setInputStream(null);
_isInput = _channel.getInputStream();
_isOutput = _channel.getOutputStream();
_reader = new BufferedReader (new InputStreamReader(_isInput));
_writer = new BufferedWriter (new OutputStreamWriter (_isOutput));
_channel.connect(3000);
LastLogin = _reader.readLine(); //get last login message
}//try to connect
catch (JSchException ex)
{
throw ex;
}
catch (UnsupportedEncodingException uee)
{
return false;
}
catch (IOException ioe)
{
return false;
}
return true;
}
这是我的执行方法。我知道有更好的方法可以从char []到ArrayList,但我还没有解决这个问题。
public List<String> ExecuteCommand (String command)
{
List<String> returns = new ArrayList();
try {
_writer.write(command);
if ( !command.endsWith("\n") )
_writer.write("\n");
_writer.flush();
Thread.sleep(2000); //allow time to exec
int c;
StringBuilder response= new StringBuilder();
while (_reader.ready()) {
c = _reader.read();
if (c == -1)
break;
response.append( (char)c ) ;
}//while
String[] lines = response.toString().split("\n");
for (String line: lines)
{
if (line.trim().length()!=0)
returns.add(line);
}
}//try
catch (IOException e)
{
//handle this later
}//catch
catch (InterruptedException ie)
{
//handle this later
}
return returns;
}//ExecuteCommand
我知道它不是很好但是有效。