groovy在远程服务器上执行shell命令 [英] groovy executing shell commands on remote server

查看:601
本文介绍了groovy在远程服务器上执行shell命令的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在远程服务器上执行shell命令时遇到问题.

我正在尝试各种解决方案,并且有一个可行的解决方案,但是在维护方面还没有进行优化:我使用一个批处理文件来启动腻子,该腻子连接到远程服务器并发送命令.

即. groovy中:

def batchFile = "C:\\Validation\\Tests_Auto\\Scripts\\remote_process\\setOldDate.bat"
Runtime.runtime.exec(batchFile)

并在我的批处理文件中:

c:
cd C:\Validation\Tests_Auto\Scripts\remote_process\
putty.exe -ssh root@xx.xx.xx.xx -pw **** -m "C:\Validation\Tests_Auto\Scripts\remote_process\setOldDate.txt"

setOldDate.txt包含命令date -s @1522018800

这有效.但是,我想以一种更简洁的方式启动它,或者避免在命令中使用文本文件,或者更好的是避免使用腻子. 我尝试了另一种方法来做同样的事情,但是没有用.我想我不太远,但是我需要一点帮助.

我试图通过ssh启动直接命令:

Runtime.getRuntime().exec('"c:\\Program Files\\OpenSSH\\bin\\ssh.exe" root:****@xx.xx.xx.xx date -s @1522018800')

如果有人可以提供帮助,我将不胜感激

谢谢

解决方案

最后,编译我的各种研究并努力适应我的环境限制(soapui中的Groovy),最终得到了以下对我有用的解决方案:

下载jsch-0.1.54.jar并将其设置在C:\ Program Files \ SmartBear \ ReadyAPI-2.3.0 \ bin \ ext

使用以下常规脚本:

import java.util.Properties
import com.jcraft.jsch.ChannelExec
import com.jcraft.jsch.JSch
import com.jcraft.jsch.Session


def ip = context.expand( '${#Project#projectEndpoint}' )


    try
    {
        JSch jsch = new JSch();
          Session session = jsch.getSession("root","$ip", 22);
          session.setPassword("****");

          // Avoid asking for key confirmation
          Properties prop = new Properties();
          prop.put("StrictHostKeyChecking", "no");
          session.setConfig(prop);

          session.connect();


        // SSH Channel
        ChannelExec channelssh = (ChannelExec)session.openChannel("exec");

            // Execute command
            //channelssh.setCommand("date -s @1520018000"); // change date
            channelssh.setCommand("ntpdate -u pool.ntp.org"); // restore date
            channelssh.connect();
            channelssh.disconnect();



    }
    catch (Exception e)
    {
        log.info "exception : " + e
      System.out.println(e.getMessage());
    }
    finally
    {
            session.disconnect();
    }

升级

这是我随着需求的发展做出的概括.以下仍在使用jsch的脚本允许发送任何命令. 这涉及主机检查,并消除了由于没有主机检查而导致的危险. 用户名和密码作为参数传递

import java.util.Properties
import com.jcraft.jsch.ChannelExec
import com.jcraft.jsch.JSch
import com.jcraft.jsch.Session

import java.util.regex.Pattern

def ip = context.expand( '${get endpoint#endpoint}' )
ip = ip.replaceFirst("http[s]?://","")

def user = context.expand( '${#Project#ssh_user}' )
def password = context.expand( '${#Project#ssh_password}' )

def command = context.expand( '${#TestCase#command}' )

def timeout = context.expand( '${#TestCase#timeout_ms}' )
if (timeout == "")
    timeout = 1000 // default timeout 1s
else
    timeout = timeout.toInteger()

log.info "command = " + command

Session session
try
{
    JSch jsch = new JSch();

    session = jsch.getSession(user,ip, 22);
    session.setPassword(password);
    //log.info "user : $user"
    //log.info "set password : $password"

    //log.info System.getProperty("user.home")+"/.ssh/known_hosts"
    jsch.setKnownHosts(System.getProperty("user.home")+"/.ssh/known_hosts");

    session.connect();
    //log.info "session connect"


    // SSH Channel
    ChannelExec channelssh = (ChannelExec)session.openChannel("exec");

    // Execute command
    channelssh.setCommand(command);
    InputStream commandOutput = channelssh.getInputStream();

    channelssh.connect();

    int readByte = commandOutput.read();

    outputBuffer = [];

    // timeout to avoid infinite loop
    while((readByte != -1) && (timeout > 0))
    {
        outputBuffer.add(readByte)
        readByte = commandOutput.read();
        timeout = timeout -1
    }

    // process output
    outputBuffer = outputBuffer as byte[]

    // convert byte array into string
    output = new String(outputBuffer, "UTF-8")

    sleep(3000)
    //log.info "disconnect"
    channelssh.disconnect();

    testRunner.testCase.setPropertyValue("cmd_output", output)
}
catch (Exception e)
{
    msg = "exception : " + e
    log.error msg
    testRunner.fail(msg)
}
finally
{
    session.disconnect();
}

I have an issue about executing shell commands on a remote server.

I'm trying various solutions and I have one working but it is not optimized in terms of maintenance : I use a batch file that launches putty which connects to the remote server ans sends the command.

ie. in groovy :

def batchFile = "C:\\Validation\\Tests_Auto\\Scripts\\remote_process\\setOldDate.bat"
Runtime.runtime.exec(batchFile)

and in my batch file :

c:
cd C:\Validation\Tests_Auto\Scripts\remote_process\
putty.exe -ssh root@xx.xx.xx.xx -pw **** -m "C:\Validation\Tests_Auto\Scripts\remote_process\setOldDate.txt"

setOldDate.txt contains the command date -s @1522018800

This works. However I'd like to launch it in a cleaner way, either avoiding the use of text file for the command or, better, avoiding using putty. I tried several another way to do the same thing but it doesn't work. I think I'm not too far but I need a little help.

I tried to launch a direct command via ssh:

Runtime.getRuntime().exec('"c:\\Program Files\\OpenSSH\\bin\\ssh.exe" root:****@xx.xx.xx.xx date -s @1522018800')

I'd be grateful if anyone could help

thanks

解决方案

Finally, compiling my various research and struggling to fit my environment constraints (groovy in soapui), I ended up with the following solution that works for me :

download jsch-0.1.54.jar and set it in C:\Program Files\SmartBear\ReadyAPI-2.3.0\bin\ext

use the following groovy script :

import java.util.Properties
import com.jcraft.jsch.ChannelExec
import com.jcraft.jsch.JSch
import com.jcraft.jsch.Session


def ip = context.expand( '${#Project#projectEndpoint}' )


    try
    {
        JSch jsch = new JSch();
          Session session = jsch.getSession("root","$ip", 22);
          session.setPassword("****");

          // Avoid asking for key confirmation
          Properties prop = new Properties();
          prop.put("StrictHostKeyChecking", "no");
          session.setConfig(prop);

          session.connect();


        // SSH Channel
        ChannelExec channelssh = (ChannelExec)session.openChannel("exec");

            // Execute command
            //channelssh.setCommand("date -s @1520018000"); // change date
            channelssh.setCommand("ntpdate -u pool.ntp.org"); // restore date
            channelssh.connect();
            channelssh.disconnect();



    }
    catch (Exception e)
    {
        log.info "exception : " + e
      System.out.println(e.getMessage());
    }
    finally
    {
            session.disconnect();
    }

UPGRADE

Here is a generalization I've made as my needs evolved. The following script, still using jsch allows to send any command. This deals with host checking and eliminates hazards due to no host checking. User and password are passed as parameters

import java.util.Properties
import com.jcraft.jsch.ChannelExec
import com.jcraft.jsch.JSch
import com.jcraft.jsch.Session

import java.util.regex.Pattern

def ip = context.expand( '${get endpoint#endpoint}' )
ip = ip.replaceFirst("http[s]?://","")

def user = context.expand( '${#Project#ssh_user}' )
def password = context.expand( '${#Project#ssh_password}' )

def command = context.expand( '${#TestCase#command}' )

def timeout = context.expand( '${#TestCase#timeout_ms}' )
if (timeout == "")
    timeout = 1000 // default timeout 1s
else
    timeout = timeout.toInteger()

log.info "command = " + command

Session session
try
{
    JSch jsch = new JSch();

    session = jsch.getSession(user,ip, 22);
    session.setPassword(password);
    //log.info "user : $user"
    //log.info "set password : $password"

    //log.info System.getProperty("user.home")+"/.ssh/known_hosts"
    jsch.setKnownHosts(System.getProperty("user.home")+"/.ssh/known_hosts");

    session.connect();
    //log.info "session connect"


    // SSH Channel
    ChannelExec channelssh = (ChannelExec)session.openChannel("exec");

    // Execute command
    channelssh.setCommand(command);
    InputStream commandOutput = channelssh.getInputStream();

    channelssh.connect();

    int readByte = commandOutput.read();

    outputBuffer = [];

    // timeout to avoid infinite loop
    while((readByte != -1) && (timeout > 0))
    {
        outputBuffer.add(readByte)
        readByte = commandOutput.read();
        timeout = timeout -1
    }

    // process output
    outputBuffer = outputBuffer as byte[]

    // convert byte array into string
    output = new String(outputBuffer, "UTF-8")

    sleep(3000)
    //log.info "disconnect"
    channelssh.disconnect();

    testRunner.testCase.setPropertyValue("cmd_output", output)
}
catch (Exception e)
{
    msg = "exception : " + e
    log.error msg
    testRunner.fail(msg)
}
finally
{
    session.disconnect();
}

这篇关于groovy在远程服务器上执行shell命令的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆