1. Jar包:ganymed-ssh2-build210.jar
2. 步驟:
a) 連接:
Connection conn = new Connection(ipAddr);
conn.connect();
b)認證:
boolean authenticateVal = conn.authenticateWithPassword(userName, password);
c) 打開一個Session:
if(authenticateVal)
Session session = conn.openSession();
d) 執行Shell命令:
1)若是執行簡單的Shell命令:(如 jps 、last 這樣的命令 )
session.execCommand(cmd);
2) 遇到問題:
用方法execCommand執行Shell命令的時候,會遇到獲取不全環境變量的問題,
比如執行 hadoop fs -ls 可能會報找不到hadoop 命令的異常
試着用execCommand執行打印環境變量信息的時候,輸出的環境變量不完整
與Linux主機建立連接的時候會默認讀取環境變量等信息
可能是因為session剛剛建立還沒有讀取完默認信息的時候,execCommand就執行了Shell命令
解決:
所以換了另外一種方式來執行Shell命令:
// 建立虛擬終端
session.requestPTY("bash");
// 打開一個Shell
session.startShell();
// 准備輸入命令
PrintWriter out = new PrintWriter(session.getStdin());
// 輸入待執行命令
out.println(cmd);
out.println("exit")
// 6. 關閉輸入流
out.close();
// 7. 等待,除非1.連接關閉;2.輸出數據傳送完畢;3.進程狀態為退出;4.超時
session.waitForCondition(ChannelCondition.CLOSED | ChannelCondition.EOF | ChannelCondition.EXIT_STATUS , 30000);
用這種方式執行Shell命令,會避免環境變量讀取不全的問題,第7步里有許多標識可以用,比如當exit命令執行后或者超過了timeout時間,則session關閉
這里需要注意,當一個Shell命令執行時間過長時,會遇到ssh連接超時的問題,
解決辦法:
1. 之前通過把Linux主機的sshd_config的參數ClientAliveInterval設為60,同時將第7步中timeout時間設置很大,來保證命令執行完畢,
因為是執行Mahout中一個聚類算法,耗時最少7、8分鍾,數據量大的話,需要幾個小時。
2. 后來將命令改成了nohup的方式執行,nohup hadoop jar .... >> XXX.log && touch XXX.log.end &
這種方式是提交到后台執行,即使當前連接斷開也會繼續執行,把命令的輸出結果寫入日志,如果hadoop命令執行成功,則生成.end文件
獲取文件的方法 ganymed-ssh2-build210.jar 也提供了,如下
SCPClient scpClient = con.createSCPClient();
scpClient.get("remoteFiles","localDirectory"); //從遠程獲取文件
e) 獲取Shell命令執行結果:
InputStream stderr = new StreamGobbler(session.getStderr());
InputStream in = new StreamGobbler(session.getStdout());

1 private String processStdErr(InputStream in, String charset) 2 throws IOException { 3 BufferedReader br = new BufferedReader(new InputStreamReader(in, charset)); 4 StringBuffer sb = new StringBuffer(); 5 6 if (in.available() != 0) { 7 while (true) { 8 String line = br.readLine(); 9 if (line == null) 10 break; 11 sb.append(line).append(System.getProperty("line.separator")); 12 } 13 } 14 15 return sb.toString(); 16 }