ALL is Well!

          敏捷是一條很長的路,摸索著前進著

            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
            30 隨筆 :: 23 文章 :: 71 評論 :: 0 Trackbacks
          此程序需要ganymed-ssh2-build210.jar包。
          下載地址:http://www.ganymed.ethz.ch/ssh2/
          為了調(diào)試方便,可以將\ganymed-ssh2-build210\src下的代碼直接拷貝到我們的工程里,
          此源碼的好處就是沒有依賴很多其他的包,拷貝過來干干凈凈。

          此程序的目的是執(zhí)行遠程機器上的Shell腳本。
          遠程機器IP:***.**.**.***
          用戶名:sshapp
          密碼:sshapp
          登錄后用pwd命令,顯示當前目錄為:/sshapp.
          在/sshapp/myshell/目錄下有myTest.sh文件,內(nèi)容如下:
          echo $1 $2 $#
          #print $1

          我們的Java代碼RmtShellExecutor.java:
          /**
           * 遠程執(zhí)行shell腳本類
           * 
          @author l
           
          */

          public class RmtShellExecutor {
              
              
          /**  */
              
          private Connection conn;
              
          /** 遠程機器IP */
              
          private String     ip;
              
          /** 用戶名 */
              
          private String     usr;
              
          /** 密碼 */
              
          private String     psword;
              
          private String     charset = Charset.defaultCharset().toString();

              
          private static final int TIME_OUT = 1000 * 5 * 60;

              
          /**
               * 構造函數(shù)
               * 
          @param param 傳入?yún)?shù)Bean 一些屬性的getter setter 實現(xiàn)略
               
          */

              
          public RmtShellExecutor(ShellParam param) {
                  
          this.ip = param.getIp();
                  
          this.usr = param.getUsername();
                  
          this.psword = param.getPassword();
              }


              
          /**
               * 構造函數(shù)
               * 
          @param ip
               * 
          @param usr
               * 
          @param ps
               
          */

              
          public RmtShellExecutor(String ip, String usr, String ps) {
                  
          this.ip = ip;
                  
          this.usr = usr;
                  
          this.psword = ps;
              }


              
          /**
               * 登錄
               * 
               * 
          @return
               * 
          @throws IOException
               
          */

              
          private boolean login() throws IOException {
                  conn 
          = new Connection(ip);
                  conn.connect();
                  
          return conn.authenticateWithPassword(usr, psword);
              }


              
          /**
               * 執(zhí)行腳本
               * 
               * 
          @param cmds
               * 
          @return
               * 
          @throws Exception
               
          */

              
          public int exec(String cmds) throws Exception {
                  InputStream stdOut 
          = null;
                  InputStream stdErr 
          = null;
                  String outStr 
          = "";
                  String outErr 
          = "";
                  
          int ret = -1;
                  
          try {
                      
          if (login()) {
                          
          // Open a new {@link Session} on this connection
                          Session session = conn.openSession();
                          
          // Execute a command on the remote machine.
                          session.execCommand(cmds);
                          
                          stdOut 
          = new StreamGobbler(session.getStdout());
                          outStr 
          = processStream(stdOut, charset);
                          
                          stdErr 
          = new StreamGobbler(session.getStderr());
                          outErr 
          = processStream(stdErr, charset);
                          
                          session.waitForCondition(ChannelCondition.EXIT_STATUS, TIME_OUT);
                          
                          System.out.println(
          "outStr=" + outStr);
                          System.out.println(
          "outErr=" + outErr);
                          
                          ret 
          = session.getExitStatus();
                      }
           else {
                          
          throw new AppException("登錄遠程機器失敗" + ip); // 自定義異常類 實現(xiàn)略
                      }

                  }
           finally {
                      
          if (conn != null{
                          conn.close();
                      }

                      IOUtils.closeQuietly(stdOut);
                      IOUtils.closeQuietly(stdErr);
                  }

                  
          return ret;
              }


              
          /**
               * 
          @param in
               * 
          @param charset
               * 
          @return
               * 
          @throws IOException
               * 
          @throws UnsupportedEncodingException
               
          */

              
          private String processStream(InputStream in, String charset) throws Exception {
                  
          byte[] buf = new byte[1024];
                  StringBuilder sb 
          = new StringBuilder();
                  
          while (in.read(buf) != -1{
                      sb.append(
          new String(buf, charset));
                  }

                  
          return sb.toString();
              }


              
          public static void main(String args[]) throws Exception {
                  RmtShellExecutor exe 
          = new RmtShellExecutor("***.**.**.***""sshapp""sshapp");
                  
          // 執(zhí)行myTest.sh 參數(shù)為java Know dummy
                  System.out.println(exe.exec("sh /webapp/myshell/myTest.sh java Know dummy"));
          //        exe.exec("uname -a && date && uptime && who");
              }

          }

          執(zhí)行后結果:
          outStr=java Know 3
          outErr
          =
          0 // getExitStatus方法的返回值

           注:一般情況下shell腳本正常執(zhí)行完畢,getExitStatus方法返回0。
          此方法通過遠程命令取得Exit Code/status。但并不是每個server設計時都會返回這個值,如果沒有則會返回null。
          在調(diào)用getExitStatus時,要先調(diào)用WaitForCondition方法,通過ChannelCondition.java接口的定義可以看到每個條件的具體含義。見以下代碼:
          ChannelCondition.java
          package ch.ethz.ssh2;

          /**
           * Contains constants that can be used to specify what conditions to wait for on
           * a SSH-2 channel (e.g., represented by a {
          @link Session}).
           *
           * 
          @see Session#waitForCondition(int, long)
           *
           * 
          @author Christian Plattner, plattner@inf.ethz.ch
           * 
          @version $Id: ChannelCondition.java,v 1.6 2006/08/11 12:24:00 cplattne Exp $
           
          */


          public abstract interface ChannelCondition
          {
              
          /**
               * A timeout has occurred, none of your requested conditions is fulfilled.
               * However, other conditions may be true - therefore, NEVER use the "=="
               * operator to test for this (or any other) condition. Always use
               * something like <code>((cond & ChannelCondition.CLOSED) != 0)</code>.
               
          */

              
          public static final int TIMEOUT = 1;

              
          /**
               * The underlying SSH-2 channel, however not necessarily the whole connection,
               * has been closed. This implies <code>EOF</code>. Note that there may still
               * be unread stdout or stderr data in the local window, i.e, <code>STDOUT_DATA</code>
               * or/and <code>STDERR_DATA</code> may be set at the same time.
               
          */

              
          public static final int CLOSED = 2;

              
          /**
               * There is stdout data available that is ready to be consumed.
               
          */

              
          public static final int STDOUT_DATA = 4;

              
          /**
               * There is stderr data available that is ready to be consumed.
               
          */

              
          public static final int STDERR_DATA = 8;

              
          /**
               * EOF on has been reached, no more _new_ stdout or stderr data will arrive
               * from the remote server. However, there may be unread stdout or stderr
               * data, i.e, <code>STDOUT_DATA</code> or/and <code>STDERR_DATA</code>
               * may be set at the same time.
               
          */

              
          public static final int EOF = 16;

              
          /**
               * The exit status of the remote process is available.
               * Some servers never send the exist status, or occasionally "forget" to do so.
               
          */

              
          public static final int EXIT_STATUS = 32;

              
          /**
               * The exit signal of the remote process is available.
               
          */

              
          public static final int EXIT_SIGNAL = 64;

          }

          當我們把myTest.sh修改為如下內(nèi)容:
          echo $1 $2 $#
          print $1
          由于我使用的linux機器上沒有print命令,所以print $1會報錯:command not found。

          接下來再讓我們執(zhí)行一下,看看控制臺的結果:
          outStr=java Know 3
          outErr
          =/sshapp/myshell/myTest.sh: line 2: print: command not found
          127
          此時shell腳本出現(xiàn)錯誤,getExitStatus方法返回127.

          在實際應用中,可以將outStr和outErr記錄到日志中,以便維護人員查看shell的執(zhí)行情況,
          而getExitStatus的返回值,可以認為是此次執(zhí)行是否OK的標準。

          其他代碼請看\ganymed-ssh2-build210\examples\下的例子吧。

          本文為原創(chuàng),歡迎轉(zhuǎn)載,轉(zhuǎn)載請注明出處BlogJava
          posted on 2010-09-26 13:03 李 明 閱讀(13610) 評論(7)  編輯  收藏 所屬分類: Java

          評論

          # re: Java SSH遠程執(zhí)行Shell腳本實現(xiàn) 2010-09-26 22:22 大道至簡
          我雖不是很明白,但感覺寫的很好哈!  回復  更多評論
            

          # re: Java SSH遠程執(zhí)行Shell腳本實現(xiàn) 2011-02-25 19:52 wx
          有批量執(zhí)行命令的例子嗎?  回復  更多評論
            

          # re: Java SSH遠程執(zhí)行Shell腳本實現(xiàn) 2011-02-28 11:06 Ronaldo
          @wx
          不好意思,沒有寫過。
          自己實現(xiàn)一下吧,大概原理應該差不多。  回復  更多評論
            

          # re: Java SSH遠程執(zhí)行Shell腳本實現(xiàn) 2012-02-06 17:20 asialee
          ssh2和JSch那個性能好?  回復  更多評論
            

          # re: Java SSH遠程執(zhí)行Shell腳本實現(xiàn) 2013-05-19 02:21 cnskylee
          ShellParam 是什么?而且導入的包也不寫出來,還有IOUtil是你自己寫的?還是什么包里面的啊?  回復  更多評論
            

          # re: Java SSH遠程執(zhí)行Shell腳本實現(xiàn) 2013-05-19 02:23 cnskylee
          JavaSFTP可以連接主機,執(zhí)行文件操作;JavaSSH主要是連接遠程主機,執(zhí)行shell腳本。菜鳥的初解  回復  更多評論
            

          # re: Java SSH遠程執(zhí)行Shell腳本實現(xiàn) 2015-04-06 23:36 tlone
          請問如果腳本中的命令為top的話請問該怎么返回執(zhí)行結果呢?  回復  更多評論
            

          主站蜘蛛池模板: 原平市| 应城市| 光山县| 华安县| 江达县| 成安县| 利辛县| 邹平县| 南充市| 丰顺县| 桐乡市| 巢湖市| 广西| 都匀市| 仪征市| 金沙县| 普陀区| 荔浦县| 游戏| 万载县| 高雄县| 顺平县| 铜山县| 马鞍山市| 镇康县| 措美县| 阜康市| 麦盖提县| 鸡西市| 海宁市| 固镇县| 木兰县| 安泽县| 恭城| 迭部县| 威远县| 德兴市| 西乌| 深圳市| 桦甸市| 雅安市|