<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    ALL is Well!

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

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

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

    我們的Java代碼RmtShellExecutor.java:
    /**
     * 遠程執行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;

        
    /**
         * 構造函數
         * 
    @param param 傳入參數Bean 一些屬性的getter setter 實現略
         
    */

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


        
    /**
         * 構造函數
         * 
    @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);
        }


        
    /**
         * 執行腳本
         * 
         * 
    @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); // 自定義異常類 實現略
                }

            }
     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");
            
    // 執行myTest.sh 參數為java Know dummy
            System.out.println(exe.exec("sh /webapp/myshell/myTest.sh java Know dummy"));
    //        exe.exec("uname -a && date && uptime && who");
        }

    }

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

     注:一般情況下shell腳本正常執行完畢,getExitStatus方法返回0。
    此方法通過遠程命令取得Exit Code/status。但并不是每個server設計時都會返回這個值,如果沒有則會返回null。
    在調用getExitStatus時,要先調用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修改為如下內容:
    echo $1 $2 $#
    print $1
    由于我使用的linux機器上沒有print命令,所以print $1會報錯:command not found。

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

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

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

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

    評論

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

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

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

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

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

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

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

    主站蜘蛛池模板: 久久精品亚洲日本佐佐木明希| 成年大片免费视频播放一级| 国产亚洲精品AA片在线观看不加载 | 亚洲视频一区在线| 亚洲一区二区精品视频| 67194成是人免费无码| 久久精品视频免费看| 成人免费视频一区二区| 亚洲日韩在线中文字幕综合 | 久久毛片免费看一区二区三区| 亚洲午夜理论片在线观看| 亚洲精品动漫在线| 国产成A人亚洲精V品无码性色 | 一级做a爰黑人又硬又粗免费看51社区国产精品视| 亚洲午夜国产精品无卡| 久久久国产精品亚洲一区| 亚洲色欲久久久综合网| 亚洲精品无码激情AV| 国产免费小视频在线观看| 午夜毛片不卡免费观看视频| 91香蕉视频免费| 国产香蕉免费精品视频| 亚洲精品视频免费在线观看| 四虎影视成人永久免费观看视频| a级毛片毛片免费观看久潮喷| jizz免费观看| 最新久久免费视频| a级片在线免费看| 久草免费手机视频| 无码精品一区二区三区免费视频 | MM131亚洲国产美女久久| 免费人成在线观看播放国产 | 日韩在线视频免费| 一级毛片**免费看试看20分钟| 免费播放国产性色生活片| 国产亚洲精品仙踪林在线播放| 看全免费的一级毛片| 国产偷国产偷亚洲高清人| 男人的天堂av亚洲一区2区| 色欲aⅴ亚洲情无码AV| 怡红院亚洲红怡院在线观看|