jsch中ChannelShell與ChannelExec的區(qū)別及說明
環(huán)境
- jdk:java7
- 操作系統(tǒng): win7
因?yàn)榭蚣?code>jsch比較老,所以對java
版本要求好低。
分析
框架jsch
我就不說了,很老的框架,現(xiàn)在也不更新了。
官網(wǎng):http://www.jcraft.com/jsch/
最近在用jsch
中的ChannelShell
時(shí),遇到問題:
①這個方法會返回命令提示符
很煩;
比如我要執(zhí)行下面幾個命令:
ChannelShell channel = (ChannelShell) session.openChannel("shell"); channel.connect(); InputStream inputStream = channel.getInputStream(); OutputStream outputStream = channel.getOutputStream(); String cmd = "ls \n\r"; outputStream.write(cmd.getBytes()); String cmd2 = "cd /home/jenkins/workspace/ggservice \n\r"; outputStream.write(cmd2.getBytes()); String cmd3 = "pwd \n\r"; outputStream.write(cmd3.getBytes()); outputStream.flush(); BufferedReader in = new BufferedReader(new InputStreamReader(inputStream)); String msg = null; while((msg = in.readLine())!=null){ System.out.println(msg); } in.close();
得到的結(jié)果是:
Last login: Fri Apr 28 15:07:22 2017 from 192.168.52.63
ls
cd /home/jenkins/workspace/ggservice
pwd
[root@master01 ~]# ls
bintray-sbt-rpm.repo tables_mysql_innodb.sql
[root@master01 ~]#
[root@master01 ~]# cd /home/jenkins/workspace/ggservice
[root@master01 ggservice]#
[root@master01 ggservice]# pwd
/home/jenkins/workspace/ggservice
[root@master01 ggservice]#
可以看出,連[root@master01 ~]
這樣的命令提示符和輸入的命令都出來,我其實(shí)是不需要這個,我要的只是結(jié)果。
②由于使用BufferedReader的readLine()方法
結(jié)果會產(chǎn)生阻塞。
BufferedReader in = new BufferedReader(new InputStreamReader(inputStream)); String msg = null; while((msg = in.readLine())!=null){//當(dāng)所有的命令都執(zhí)行完畢后,就會產(chǎn)生阻塞 System.out.println(msg); } in.close();
如下圖:
為什么會這樣呢?
因?yàn)槲覀兘⒌氖?code>shell管道,并且我們又使用readLine
方法,當(dāng)命令全部執(zhí)行完畢后,遠(yuǎn)程端并不知道執(zhí)行完畢,還在等待接受數(shù)據(jù),所以呢reandLine
就一直阻塞在那里。
即便你換成read
方法還是一樣的,因?yàn)?code>shell管道本身就是交互模式的。
要想停止,有兩種方式
①人為的發(fā)送一個exit
命令,告訴程序本次交互結(jié)束啦
②使用字節(jié)流中的available
方法,來獲取數(shù)據(jù)的總大小,然后循環(huán)去讀。
- ①代碼:
InputStream inputStream = channel.getInputStream();//從遠(yuǎn)程端到達(dá)的所有數(shù)據(jù)都能從這個流中讀取到 OutputStream outputStream = channel.getOutputStream();//寫入該流的所有數(shù)據(jù)都將發(fā)送到遠(yuǎn)程端。 //使用PrintWriter流的目的就是為了使用println這個方法 //好處就是不需要每次手動給字符串加\n PrintWriter printWriter = new PrintWriter(outputStream); String cmd = "ls"; printWriter.println(cmd); String cmd2 = "cd /home/jenkins/workspace/ggservice"; printWriter.println(cmd2); String cmd3 = "ls"; printWriter.println(cmd3); printWriter.println("exit");//加上個就是為了,結(jié)束本次交互 printWriter.flush(); BufferedReader in = new BufferedReader(new InputStreamReader(inputStream)); String msg = null; while((msg = in.readLine())!=null){ System.out.println(msg); } in.close();
- ②代碼:
...代碼省略 ... ChannelShell channel = (ChannelShell) session.openChannel("shell"); channel.connect(); //從遠(yuǎn)程端到達(dá)的所有數(shù)據(jù)都能從這個流中讀取到 InputStream in = channel.getInputStream(); //寫入該流的所有數(shù)據(jù)都將發(fā)送到遠(yuǎn)程端。 OutputStream outputStream = channel.getOutputStream(); byte[] tmp=new byte[1024]; while(true){ while(in.available()>0){ int i=in.read(tmp, 0, 1024); if(i<0)break; System.out.print(new String(tmp, 0, i)); } if(channel.isClosed()){ if(in.available()>0) continue; System.out.println("exit-status: "+channel.getExitStatus()); break; } }
這樣就不會阻塞啦
最后我就去查ChannelShell和ChannelExec區(qū)別
ChannelShell
對于ChannelShell,以輸入流的形式,提供命令和輸入這些命令,這就像在本地計(jì)算機(jī)上使用交互式shell(它通常用于:交互式使用)
ChannelExec
對于ChannelExec,在調(diào)用connect()方法之前這個命令提供了setCommand()方法,
并且這些命令作為輸入將以輸入流的形式被發(fā)送出去。
(通常,你只能有調(diào)用setCommand()方法一次,多次調(diào)用只有最后一次生效),
但是你可以使用普通shell的分隔符(&,&&,|,||,; , \n, 復(fù)合命令)來提供多個命令。
這就像在你本機(jī)上執(zhí)行一個shell腳本一樣(當(dāng)然,如果一個命令本身就是個交互式shell,這樣就像ChannelShell)
明顯:使用命令通道更容易,因?yàn)槟恍枰幚砻钐崾痉?/p>
總結(jié)
以上為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持腳本之家。
參考鏈接:
相關(guān)文章
Java 利用DeferredResult實(shí)現(xiàn)http輪詢實(shí)時(shí)返回?cái)?shù)據(jù)接口
這篇文章主要介紹了Java 利用 DeferredResult 實(shí)現(xiàn) http 輪詢實(shí)時(shí)返回?cái)?shù)據(jù)接口,幫助大家更好的理解和學(xué)習(xí)使用Java,感興趣的朋友可以了解下2021-03-03使用Apache?POI和SpringBoot實(shí)現(xiàn)Excel文件上傳和解析功能
在現(xiàn)代企業(yè)應(yīng)用開發(fā)中,數(shù)據(jù)的導(dǎo)入和導(dǎo)出是一項(xiàng)常見且重要的功能需求,Excel?作為一種廣泛使用的電子表格工具,常常被用來存儲和展示數(shù)據(jù),下面我們來看看如何使用Apache?POI和SpringBoot實(shí)現(xiàn)Excel文件上傳和解析功能吧2025-01-01