Java 从远程Python脚本返回值

Java 从远程Python脚本返回值,java,python,ssh,remote-access,jsch,Java,Python,Ssh,Remote Access,Jsch,我通过JSch从本地Java代码调用远程Python脚本。 当我在Python框上从Java执行“ls”时,它返回正确的结果(连接正常)。然后我编写了一个小程序,返回字符串“hello world”。在Java方面,结果是空白的。通常,如果在终端上输出某个内容,则返回该内容,但不返回变量 Java代码: import com.jcraft.jsch.*; import java.io.IOException; import java.io.InputStream; import java.uti

我通过JSch从本地Java代码调用远程Python脚本。 当我在Python框上从Java执行“ls”时,它返回正确的结果(连接正常)。然后我编写了一个小程序,返回字符串“hello world”。在Java方面,结果是空白的。通常,如果在终端上输出某个内容,则返回该内容,但不返回变量

Java代码:

import com.jcraft.jsch.*;
import java.io.IOException;
import java.io.InputStream;
import java.util.logging.Level;
import java.util.logging.Logger;

public class SSHManager
{
private static final Logger LOGGER = Logger.getLogger(SSHManager.class.getName());
private JSch jschSSHChannel;
private String strUserName;
private String strConnectionIP;
private int intConnectionPort;
private String strPassword;
private Session sesConnection;
private int intTimeOut;

private void doCommonConstructorActions(String userName, String password,
        String connectionIP, String knownHostsFileName)
{
    jschSSHChannel = new JSch();

    try
    {
        jschSSHChannel.setKnownHosts(knownHostsFileName);
    }
    catch(JSchException jschX)
    {
        logError(jschX.getMessage());
    }

    strUserName = userName;
    strPassword = password;
    strConnectionIP = connectionIP;
}

public SSHManager(String userName, String password, 
        String connectionIP, String knownHostsFileName)
{
    doCommonConstructorActions(userName, password, 
            connectionIP, knownHostsFileName);
    intConnectionPort = 22;
    intTimeOut = 60000;
}

public SSHManager(String userName, String password, String connectionIP, 
        String knownHostsFileName, int connectionPort)
{
    doCommonConstructorActions(userName, password, connectionIP, 
            knownHostsFileName);
    intConnectionPort = connectionPort;
    intTimeOut = 60000;
}

public SSHManager(String userName, String password, String connectionIP, 
        String knownHostsFileName, int connectionPort, int timeOutMilliseconds)
{
    doCommonConstructorActions(userName, password, connectionIP, 
            knownHostsFileName);
    intConnectionPort = connectionPort;
    intTimeOut = timeOutMilliseconds;
}

public String connect()
{
    String errorMessage = null;

    try
    {
        sesConnection = jschSSHChannel.getSession(strUserName, 
                strConnectionIP, intConnectionPort);
        sesConnection.setPassword(strPassword);
        // UNCOMMENT THIS FOR TESTING PURPOSES, BUT DO NOT USE IN PRODUCTION
        // sesConnection.setConfig("StrictHostKeyChecking", "no");

        java.util.Properties config = new java.util.Properties(); 
        config.put("StrictHostKeyChecking", "no");
        sesConnection.setConfig(config);

        sesConnection.connect(intTimeOut);
    }
    catch(JSchException jschX)
    {
        System.out.println("Connection failed.");
        errorMessage = jschX.getMessage();
    }

    return errorMessage;
}

private String logError(String errorMessage)
{
    if(errorMessage != null)
    {
        LOGGER.log(Level.SEVERE, "{0}:{1} - {2}", 
                new Object[]{strConnectionIP, intConnectionPort, errorMessage});
    }

    return errorMessage;
}

private String logWarning(String warnMessage)
{
    if(warnMessage != null)
    {
        LOGGER.log(Level.WARNING, "{0}:{1} - {2}", 
                new Object[]{strConnectionIP, intConnectionPort, warnMessage});
    }

    return warnMessage;
}

public String sendCommand(String command)
{
    StringBuilder outputBuffer = new StringBuilder();

    try
    {
        Channel channel = sesConnection.openChannel("exec");
        ((ChannelExec)channel).setCommand(command);
        channel.connect();
        InputStream commandOutput = channel.getInputStream();
        int readByte = commandOutput.read();

        while(readByte != 0xffffffff)
        {
            outputBuffer.append((char)readByte);
            readByte = commandOutput.read();
        }

        channel.disconnect();
    }
    catch(IOException ioX)
    {
        logWarning(ioX.getMessage());
        return null;
    }
    catch(JSchException jschX)
    {
        logWarning(jschX.getMessage());
        return null;
    }

    return outputBuffer.toString();
}

public void close()
{
    sesConnection.disconnect();
}
}
测试代码:

import static org.junit.Assert.*;
import org.junit.Test;

public class SSHManagerTest {
/**
 * Test of sendCommand method, of class SSHManager.
 */
@Test
public void testSendCommand()
{
    System.out.println("sendCommand");

    String command = "python /home/abc/helloworld.py";
    String userName = "abc";
    String password = "pqr";
    String connectionIP = "10.112.1.2";
    SSHManager instance = new SSHManager(userName, password, connectionIP, "");
    String errorMessage = instance.connect();

    if(errorMessage != null)
    {
        System.out.println(errorMessage);
        fail();
    }

    //String expResult = "thisOne\n";
    // call sendCommand for each command and the output 
    //(without prompts) is returned
    String result = instance.sendCommand(command);
    System.out.println(result + " (expected hello world)");
    // close only after all commands are sent
    instance.close();
    assertEquals(expResult, result);
}
}
Python代码:

#!/usr/bin/python
def main():
    return "Hello world"
剧本

#!/usr/bin/python
def main():
    return "Hello world"
不向标准输出生成任何输出,即
返回
只返回一个值,不在标准输出上打印。您可以尝试以下方法:

#!/usr/bin/env python
def main():
    print("Hello world")

注意,我还将“shebang”改为使用
env
。这通常是调用python更可靠的方法,因为它避免了路径问题。

问题不在于SSH代码。您是否尝试在本地运行Python代码(在您的本地计算机上,没有SSH)?是的,请检查mhawke答案上的注释。我想将值返回到java,而不是打印到stdout。很抱歉,如果我的问题有其他含义的话。我提到stdout只是为了说明连接工作正常。@Natasha程序不会返回任何东西,除了退出代码(是单字节数,SSH仍然不会将它们发送到客户端)。好吧,你不能通过SSH像那样返回字符串。您提到了将远程运行
ls
作为一个测试—输出到stdout。你不能收集远程进程的stdout并使用它是有原因的吗?好的,我的方法可能是错误的,让我描述一下我的问题。我的java代码将在远程框上调用Python脚本。这个Python脚本依次执行某些操作并以JSON格式返回多个ID。我需要将这些ID返回java。只需将ID写在远程进程的标准输出上,并在java代码中读取它。这就是java函数
sendCommand()
中已经发生的情况-它以字符串形式返回远程命令的输出。