• 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏吧

通过Java JSch库在远程计算机上执行本地脚本

java 来源:Shubham Khatri 12次浏览

我正在监视一组远程服务器上的错误的日志。为此,我正在监视在一段时间内被修改的日志。通过Java JSch库在远程计算机上执行本地脚本

我使用Jsch Java library来制作SSH connection并执行命令。正如我所搜索的,多个命令可以通过将不同命令分开的远程机器通过;

为此我有一个文本文件,其中包含我在其上建立连接的远程主机上的列表。我意识到,我可以通过下面的命令

find . -mmin -60 -type f -exec ls {} + 

不,我可以遍历文件和grep for the Error修改的所有文件的列表。为此,我写了下面的脚本

logTestScript.sh

#!/bin/bash 

cd /log 
searchString='<Error ErrorCode="java.sql.SQLException"' 
files=`find . -mmin -60 -type f -exec ls {} +` 
pwd 
hostname 
echo ${files} 
for file in ${files[@]} 
do 
     if grep -Fq "$searchString" $file 
     then 
       echo "String found in $file" 
     fi 
done 

现在这个脚本会在当前包从我运行一个Java程序,我想运行在每个这个脚本的远程主机。

下面是我当前的代码利用的

private void getSSHConnection() throws IOException, JSchException { 

     username = props.getProperty("host_username"); 
     password = props.getProperty("host_password"); 
     log_traceback_interval = props.getProperty("fetch_logs_interval_minutes"); 
     errorString = props.getProperty("error_message_log"); 

     System.out.println(username + " " + password + " " + errorString); 

     // Get the hostnames resource file 
     String hostnameResourcePath = envObj.getAgentHostnamesConfig(TargetEnvironment, ManagementSystem); 
     InputStream hostInpStream = this.getClass().getResourceAsStream(hostnameResourcePath); 
     BufferedReader hostnameReader = new BufferedReader(new InputStreamReader(hostInpStream)); 

     String host = null; 

     while((host = hostnameReader.readLine()) != null) { 

      System.out.println(host); 

      // get a JSch connection object 
      JSch jschObj = new JSch(); 
      Session session = jschObj.getSession(username, host); 

      // Disable StrictHost key checking 
      Properties config = new Properties(); 
      config.put("StrictHostKeyChecking", "no"); 
      session.setConfig(config); 

      session.setPassword(password); 
      session.connect(); 

      //Execute channel instance 
      ChannelExec channelExec = (ChannelExec)session.openChannel("exec"); 
      InputStream in = channelExec.getInputStream(); 

      //Bash script command with arguments 
      StringBuilder sb = new StringBuilder(); 
      String command = sb.append("cd /log").append(";") 
           .append("echo `find . -mmin -60 -type f -exec ls {} +`").append(";") 
           .toString(); 

      System.out.println(command); 

      //Run the script on host 
      channelExec.setCommand(command); //I want to run the script here instead of each command as it uses for loop 

      channelExec.setInputStream(null); 

      channelExec.setErrStream(System.err); 

      InputStream monitorLogs = channelExec.getInputStream(); 

      channelExec.connect(); 

      //Read the logs 
      BufferedReader logReader = new BufferedReader(new InputStreamReader(monitorLogs)); 
      String logLine; 

      while((logLine = logReader.readLine()) != null) { 

       System.out.println(logLine); 
      } 

      //Close the connections 
      channelExec.disconnect(); 
      session.disconnect(); 
     } 




    } 

一个解决方案,我可以到远程主机想如果到SCP的脚本,然后执行它。

但是有没有一些简单的解决方案,即使没有编写脚本,只执行命令或在远程服务器上执行脚本,我也可以获得相同的结果。

感谢您的帮助


===========解决方案如下:

您无法在服务器上执行本地脚本。

你有两个选择(你是显然知道):

  • 上传脚本并执行它(和删除后,如果需要的话)。
  • 执行脚本的内容。如您所知,只需将所有行与;连接即可。

    虽然要小心forif。在dothen之后应该没有;

    <code class="prettyprint-override">cd /log ; searchString='<Error ErrorCode="<a href="http://www.fixbbs.com/p/tag/java" title="查看更多关于java的文章" target="_blank">java</a>.sql.SQLException"' ; files=`find . -mmin -60 -type f -exec ls {} +` ; echo `pwd` ; echo `hostname` ; echo ${files} ; for file in ${files[@]} ; do if grep -Fq "$searchString" $file ; then echo "String found in $file" ; fi ; done 
    </code>
  • 类似于之前的方法,您可以执行bash -s和写剧本的内容(命令),以它的输入。

    <code class="prettyprint-override">ChannelExec channelExec = (ChannelExec)session.openChannel("exec"); 
    channelExec.setCommand("bash -s"); 
    channelExec.connect(); 
    OutputStream out = channel.getOutputStream(); 
    FileInputStream fis = new FileInputStream("testScript.sh"); 
    byte[] buf = new byte[1024]; 
    while (true) 
    { 
        int len = fis.read(buf, 0, buf.length); 
        if (len <= 0) break; 
        out.write(buf, 0, len); 
    } 
    </code>

    以上基本上是从看似无关的SCP upload example复制 – 这个例子实际上提要本地的文件到远程scp过程 – 因此,它实际上是非常相关的。


的Ntb, “回声`pwd`” 和 “回声`hostname`” 是没有意义的。直接使用“pwd”和“主机名”。


版权声明:本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系管理员进行删除。
喜欢 (0)