一、准备环境
ruby 2.7.8
java jdk8
远程windows10专业版 22H2
二、安装ruby
1、开发机器 windows
下载ruby安装包
一路默认安装即可,记得勾选Add Ruby executables to your PATH
安装完成 cmd 输入
ruby -v
查看是否成功安装
2、生产环境 linux
tar -zxvf ruby-2.7.8.tar.gz
cd ruby-2.7.8
./configure
make
make install
#查看是否成功安装
ruby -v
源码安装如果报错通常是缺少依赖,安装下下面的依赖
yum -y install gcc gcc-c++ make autoconf libjpeg libjpeg-devel libpng libpng-devel freetype freetype-devel libxml2 libxml2-devel zlib zlib-devel glibc glibc-devel glib2 glib2-devel bzip2 bzip2-devel ncurses ncurses-devel curl-devel e2fsprogs e2fsprogs-devel krb5 krb5-devel libidn libidn-devel openssl openssl-devel openldap openldap-devel nss_ldap openldap-clients openldap-servers
三、Ruby脚本
require 'winrm-elevated'
require 'winrm'
require 'json'
class RubyClient
def initialize(hostname, username, password)
@hostname = hostname
@username = username
@password = password
@conn = WinRM::Connection.new(
endpoint: "http://#{@hostname}:5985/wsman",
user: @username,
password: @password
)
end
def execute_command(command)
result = @conn.shell(:powershell) do |shell|
shell.run(command) do |_, _|
# puts "STDOUT: #{stdout}" unless stdout.nil?
# puts "STDERR: #{stderr}" unless stderr.nil?
end
end
if result.exitcode == 0
output = result.stdout.strip
else
output = result.stderr.strip
end
# 构建 JSON 结果
json_result = { code: result.exitcode, data: output }.to_json
# 输出 JSON 结果
puts json_result
end
def upload_file(local_path, remote_path)
file_manager = WinRM::FS::FileManager.new(@conn)
result = file_manager.upload(local_path, remote_path)
if
result.to_i == 0
transfer_result = '{"code":0,"data":"transfer_success"}'
else
transfer_result = '{"code":1,"data":"transfer_fail"}'
end
puts transfer_result
end
end
client = RubyClient.new(ARGV[0], ARGV[1], ARGV[2])
execute_type = ARGV[3]
if execute_type == "upload"
return client.upload_file(ARGV[4], ARGV[5])
end
if execute_type == "command"
return client.execute_command(ARGV[4])
end
if execute_type == "multiple"
str = ARGV[4]
str_split = str.split(";")
result = ''
str_split.each do |element|
result += element.to_s + ' '
end
return client.execute_command(result)
end
#
# client = RubyClient.new('192.168.46.60', 'Administrator', 'DDDFs')
# # client.execute_command("Test-Path -Path 'E:/echo.bat'")
# client.upload_file("E:\\testTmp\\a.txt", "E:\\tmp\\a.txt")
四、Java 调用 ruby
1、导入依赖
gem install winrm
gem install winrm-elevated
2、 RubyClient
package com.info2soft.core.util;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
/**
* @Author: Lisy
* @Date: 2023/06/02/15:12
* @Description: 调用 ruby 工具类
*/
@Slf4j
public class RubyClient {
private static final boolean WINDOWS = System.getProperty("os.name").toLowerCase(Locale.ROOT).startsWith("windows");
private static final String COMMAND = "command";
private static final String UPLOAD = "upload";
private static final String MULTIPLE = "multiple";
private static final String SPACE = " ";
private final String username;
private final String password;
private final String ip;
private static final String RUBY;
private static final String RUBY_FILE;
static {
if (WINDOWS) {
// windows 开发环境替换下面文件的绝对路径
RUBY = "C:\\Ruby27-x64\\bin\\ruby.exe";
RUBY_FILE = "F:\\code\\i2drm\\drm\\agilebpm-oa-app\\src\\main\\resources\\ruby\\ruby_client.rb";
} else {
RUBY = "/usr/local/bin/ruby";
RUBY_FILE = "/usr/local/ruby_client.rb";
}
}
public RubyClient(String username, String password, String ip) {
this.username = username;
this.password = password;
this.ip = ip;
}
/**
* 判断调用ruby脚本是否成功
* @param result 调用返回结果
* @return
*/
public boolean executeSuccess(String result) {
if (StringUtils.isBlank(result)) {
return false;
}
JSONObject jsonObject = JSONObject.parseObject(result);
if (Objects.isNull(jsonObject)) {
return false;
}
return jsonObject.getInteger("code") == 0;
}
/**
* 通过ruby 远程连接winrm 执行命令
*
* @param command 需要执行的命令
* @param multiple 是否是多参数,true:则将空格的参数替换成 ';'
* 如 Test-Path -Path 'E:\\a.txt' 替换成 Test-Path;-Path;'E:/echo.bat'
* @return 执行结果
*/
public List<String> executeCommand(String command, boolean multiple) {
isInstall();
String cmdTmp = multiple ? MULTIPLE : COMMAND;
String cmd = RUBY + SPACE + RUBY_FILE + SPACE +
ip + SPACE + username + SPACE + password + SPACE +
cmdTmp + SPACE + command;
return execute(cmd);
}
public List<String> executeCommand(String command) {
return executeCommand(command, false);
}
/**
* 通过ruby 远程连接winrm 执行命令,
* @param command 需要执行的命令
* @return 返回一行执行结果
*/
public String executeCommand1Line(String command) {
return executeCommand1Line(command, false);
}
public String executeCommand1Line(String command, boolean multiple) {
List<String> strings = executeCommand(command, multiple);
return strings.get(0);
}
public String transferFile(String localFile, String remoteFile) {
isInstall();
if (!Files.exists(Paths.get(localFile))) {
throw new RuntimeException("File " + localFile + "不存在!");
}
String cmd = RUBY + SPACE + RUBY_FILE + SPACE +
ip + SPACE + username + SPACE + password + SPACE +
UPLOAD + SPACE + localFile + SPACE + remoteFile;
List<String> execute = execute(cmd);
return execute.get(0);
}
private List<String> execute(String command) {
Process proc;
List<String> result = new ArrayList<>();
try {
proc = Runtime.getRuntime().exec(command);
BufferedReader in = new BufferedReader(new InputStreamReader(proc.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
result.add(line);
}
in.close();
proc.waitFor();
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
return result;
}
private void isInstall() {
if (!Files.exists(Paths.get(RUBY_FILE))) {
throw new RuntimeException("ruby 脚本不存在:" + RUBY_FILE + "请检查此路径是否存在此文件");
}
if (!Files.exists(Paths.get(RUBY))) {
throw new RuntimeException("ruby 执行程序不存在:"+ RUBY +",请先安装!");
}
}
}
3、Ruby测试类
public class RubyTest {
RubyClient rubyClient;
@Before
public void before() {
String ip = "192.18.4.0";
String user = "123";
String pwd = "123";
rubyClient = new RubyClient(user, pwd, ip);
}
@Test
public void executeCommand() {
List<String> hostname = rubyClient.executeCommand("hostname");
hostname.forEach(System.out::println);
}
@Test
public void start() {
String hostname = rubyClient.executeCommand1Line("Test-Path;-Path;'E:/echo.bat'", true);
System.out.println("hostname = " + hostname);
}
@Test
public void transferFiletest() {
String localFile = "E:\\testTmp\\a.txt";
String hostname = rubyClient.transferFile(localFile, "E:\\tmpa\\a.txt");
System.out.println(hostname);
}
}