JSch中’shell’通道和’exec’通道之间有什么区别

我希望能够将Java应用程序中表示为字符串的许多连续命令发送到SSH服务器以供执行。 我应该使用:

Channel channel = session.openChannel("shell"); 

-要么-

 Channel channel = session.openChannel("exec"); 

使用shell通道shell(在unix上它是sh或bash或类似的东西,在Windows上它通常是cmd.exe)启动并创建控制台(如果你在本地运行它们就会在屏幕上看到)。 您有一个提示,您可以解析或用于检测命令的完成。

使用命令通道,为每个命令启动一个shell实例(实际上为每个命令打开通道),并且命令作为shell的参数传递(在Windows上它看起来像“cmd.exe / c”)。

使用命令通道更容易,因为您不需要处理命令提示符。

有关这些流之间的差异和相似之处的概述,您可以在JSch wiki中的Shell,Exec或Subsystem Channel «中找到它们。 这里有一些用例的详细信息。

exec通道中 ,命令来自您使用setCommand()提供的命令字符串。 SSH服务器会立即将它们传递给shell(使用类似bash -c '' )。

如果由于某种原因shell没有以某种方式退出,它们都将被执行。 (你可以在这里发送一个完整的shell脚本,如果需要的if ,使用if和类似的方法实现一些逻辑。)

因此,要执行多个命令,可以通过将它们分开来将它们传递给exec通道; 或换行符( \n )。 因为你不能在给出所有命令之前等待结果,所以在这里你只能使用多个exec通道(但是因为每个通道产生一个新的shell,它们不保存它们之间的状态,比如工作目录或shell变量)。

shell通道中 ,shell将从流中读取输入,并将第一行解释为命令(或多个命令)。

然后它将执行此命令。 如果需要,命令本身可能会从流中读取更多输入。

然后shell将读取下一行,将其解释为命令,然后执行。

(在某些情况下,shell必须读取多行,例如对于长字符串或组合命令,如if或loops。)

这将持续到流的末尾(例如,您身边的stream.close())或执行显式退出命令。

如果您没有通过通道输入/输出流向shell发送任何输入,那么shell将等到您发送更多或关闭流。 因此,您可以安静地读取一个命令的输出,在客户端执行一些计算,然后决定下一个要发送的命令。

只需确保不要将输入混合到一个命令和下一个命令的文本 – 最好不要使用任何从标准输入读取的命令。

好吧,我发现这是有效的,如果你想像常规shell那样保存状态会非常方便:

 Session session = jsch.getSession(user, host, 22); Channel channel = session.openChannel("shell"); OutputStream inputstream_for_the_channel = channel.getOutputStream(); PrintStream commander = new PrintStream(inputstream_for_the_channel, true); channel.setOutputStream(System.out, true); channel.connect(); commander.println("ls -la"); commander.println("cd folder"); commander.println("ls -la"); commander.println("exit"); commander.close(); do { Thread.sleep(1000); } while(!channel.isEOF()); session.disconnect(); 

你可以改变

 channel.setOutputStream(System.out, true); 

 InputStream outputstream_from_the_channel = channel.getInputStream(); BufferedReader br = new BufferedReader(new InputStreamReader(outputstream_from_the_channel)); String line; while ((line = br.readLine()) != null) System.out.print(line+"\n"); 

如果你想要更多的输出控制。

================================================== ===========================

编辑:跟进

为什么有时我通过PrintStream发送的命令会随机出现在输出中。 即以下代码:

 shell[0].println("cd .."); shell[0].println("cd .."); shell[0].println("ls -la"); shell[0].println("exit"); 

产生这个:(用{thing}标记的东西不应该存在!)

上次登录时间:2011年7月21日星期一21:49:13来自网关

清单:trunk-latest

[主持〜] $ cd ..
{cd ..} [寄宿家庭] $
[主页] $ cd ..
[主持人/] $
[host /] $ ls -la
{出口}

共9999
———- 27 root root 4096 2010年1月26日。
———- 27 root root 4096 2010年1月26日..
———- 1 root root 0 Mar 14 19:16 .autojyk
———- 1 root root 0 2009年2月9日.automan
———- 1 root root 3550 2010年5月14日.bash_history
d ——— 2 root root 4096 Apr 26 04:02 put
d ——— 5 root root 4024 Apr 25 19:31启动
[m [host /] $
[host /] $ exit
登出