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

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

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

    ALL is Well!

    敏捷是一條很長的路,摸索著前進(jìn)著

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

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

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

    public class RmtShellExecutor {
        
        
    /**  */
        
    private Connection conn;
        
    /** 遠(yuǎn)程機(jī)器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;

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

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


        
    /**
         * 構(gòu)造函數(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("登錄遠(yuǎn)程機(jī)器失敗" + ip); // 自定義異常類 實(shí)現(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í)行后結(jié)果:
    outStr=java Know 3
    outErr
    =
    0 // getExitStatus方法的返回值

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

    }

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

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

    在實(shí)際應(yīng)用中,可以將outStr和outErr記錄到日志中,以便維護(hù)人員查看shell的執(zhí)行情況,
    而getExitStatus的返回值,可以認(rèn)為是此次執(zhí)行是否OK的標(biāo)準(zhǔn)。

    其他代碼請(qǐng)看\ganymed-ssh2-build210\examples\下的例子吧。

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

    評(píng)論

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

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

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

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

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

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

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

    主站蜘蛛池模板: MM1313亚洲国产精品| 亚洲乱码在线播放| 亚洲综合无码一区二区三区| 91情国产l精品国产亚洲区| 中文字幕 亚洲 有码 在线| 激情五月亚洲色图| 色多多A级毛片免费看| 久久精品免费观看| 亚洲精品免费网站| 国产禁女女网站免费看| 亚洲香蕉网久久综合影视| 亚洲男人第一av网站| 亚洲人成欧美中文字幕| 国产精品玖玖美女张开腿让男人桶爽免费看 | 亚洲综合伊人久久大杳蕉| 亚洲日本中文字幕| 亚洲日韩国产二区无码| 一个人看的www免费高清| 99精品在线免费观看| 日韩一区二区三区免费体验| 亚洲日韩中文字幕日韩在线 | 久久久久亚洲AV片无码下载蜜桃| 国产 亚洲 中文在线 字幕 | 久久亚洲精品无码av| 在线涩涩免费观看国产精品| 欧美男同gv免费网站观看 | 亚洲综合日韩久久成人AV| 亚洲美女视频一区| 香蕉视频免费在线播放| 99在线视频免费| 国产成人一区二区三区免费视频| 狠狠色伊人亚洲综合成人| 亚洲一区二区无码偷拍| 99在线视频免费观看| 在线a毛片免费视频观看| 亚洲阿v天堂在线| 亚洲heyzo专区无码综合| 未满十八18禁止免费无码网站 | 亚洲午夜无码久久久久| 亚洲av第一网站久章草| 免费精品无码AV片在线观看|