【发布时间】:2018-08-24 18:19:24
【问题描述】:
在我的代码中,我试图通过 SSH 在远程服务器上运行一些命令。 这些命令必须相互建立,但背后有逻辑。这意味着类似: 当命令 a 的输出包含“retcode 0”时,执行命令 b。否则执行命令 c
我发现无法将这个逻辑实现到几个“exec”命令中。似乎每个“执行官”都有自己的流程,所以我不能继续我以前的工作。使用一个“exec”,我可以传递一个命令列表,所有这些命令都将在其中执行,所以那里没有逻辑。所以,我决定为 Jsch 使用“shell”。 (如果有办法使用 exec,我会很高兴的)
根据jcraft的例子,我写了这段代码:
import com.jcraft.jsch.*;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
public class Main {
public static void main(String[] args) {
try {
JSch jsch = new JSch();
String user = "sshuser";
String host = "localhost";
Session session = jsch.getSession(user, host, 22);
String passwd = "password";
session.setPassword(passwd);
session.setConfig("StrictHostKeyChecking", "no");
//session.connect();
session.connect(30000); // making a connection with timeout.
Channel channel = session.openChannel("shell");
// Enable agent-forwarding.
((ChannelShell)channel).setAgentForwarding(true);
// Set Streams
channel.setInputStream(System.in);
channel.setOutputStream(System.out);
channel.connect(3 * 1000);
} catch (Exception e) {
System.out.println(e);
}
}
}
基本上,这让我作为一个人能够做我想做的事。我可以在 System.in 中输入命令,返回打印到 System.out。我可以阅读它,决定我想用它做什么,然后输入下一个命令。该命令将在我之前的位置准确执行,所以一切都很好。
现在我必须找到一种通过 java 来实现的方法。我找到了一种通过修复字符串输入第一个命令的方法:
[...]
InputStream testInput = new ByteArrayInputStream( "dir \n".getBytes("UTF-8") );
// Set Streams
channel.setInputStream(testInput);
[...]
但是在那之后我找不到发送下一个的方法(即使没有读取输出,作为第一步)。
所以,我的问题是,有没有办法通过 Java 代码设置 System.in,该代码将直接通过 Jsch 发送(System.setIn() 对我不起作用)或其他更改方式即时输入字符串,以便通过 Jsch 传输?
感谢您的宝贵时间!
【问题讨论】:
-
您确定需要在同一个 shell 中运行命令(您错误地称之为 "process")吗?请解释一下原因。你可能错了。
-
通过命令我将更改应用程序内部的上下文。所以,第一个命令会让我登录,第二个将为命令设置特定区域,然后第三个是实际命令。据我了解,使用新的 shell 我将始终从同一个起点开始,所以在这种情况下没有登录。当有办法在最后一个结束的地方继续前进时,我可以使用新的 shell。
-
好的,所以这些不是“命令”(关于 SSH = shell 命令),而是某些应用程序的一些输入行? - 或者,如果您的“设备”实际上不是普通的 [Linux] 机器,而是一些特殊的机器?
-
命令是一些应用程序的输入行。可以使用“exec”传递此应用程序中一个任务的所有命令,但随后所有命令都会被冲进来。因此,例如,如果第一次登录成功,则无需验证。应用程序在输出的末尾总是返回一个“END”,所以很容易在流中解析它
-
那么你的问题是关于“exec”和“shell”通道的令人困惑的措辞。您实际上只执行单个顶级 [shell] 命令(应用程序)。因此,从您的问题的角度来看,如果您使用“shell”或“exec”通道并不重要,因为只有一个顶级命令。所以使用“exec”通道来避免“shell”通道出现问题。子命令(应用程序命令)需要作为输入传递给应用程序。为此,请参阅Providing input/subcommands to command executed over SSH with JSch。
标签: java ssh inputstream jsch