3

我正在用 Java 编写一个需要使用终端命令才能工作的程序。我的功能基本上是这样的:

public void sendLoginCommand() throws IOException
{
    System.out.println("\n------------Sending Login Command------------\n");
    String cmd="qskdjqhsdqsd";
    Runtime rt = Runtime.getRuntime();
    Process p=rt.exec(cmd);
}
public Process sendPassword(String password) throws IOException
{
    System.out.println("\n------------Sending Password------------\n");
    String cmd=password;
    Runtime rt = Runtime.getRuntime();
    Process p=rt.exec(cmd);
    return p;
}
public void login(String password) throws IOException
{
    sendLoginCommand();
    Process p = sendPassword(password);
    System.out.println("\n------------Reading Terminal Output------------\n");
    Reader in = new InputStreamReader(p.getInputStream());

    in = new BufferedReader(in);
    char[] buffer = new char[20];
    int len = in.read(buffer);
    String s = new String(buffer, 0, len);
    System.out.println(s);
    if(s.equals("Password invalid.")) loggedIn=false;
    else loggedIn=true;
}

在这里,程序正确发送了 p4 登录命令,但随后终端要求输入密码。当我使用与 sendLoginCommand() 相同的行时,程序返回错误。显然,我们只能通过 Process 发送标准命令。我希望有人知道如何向终端发送普通字符串

先感谢您

4

4 回答 4

3

您的直接问题是您正在为您正在调用的每个“命令”启动单独的进程。密码“command”被发送给一个完全不知道之前的“login”命令的进程。

话虽如此,您更可怕的问题是对 Process 类的用途以及如何从 Java 中与外部程序交互的严重误解。

这是一个教程,可以帮助您进一步了解该主题,我会建议其他人使用谷歌搜索。

于 2012-04-25T12:59:02.973 回答
1

我找到了我的问题的答案。

问题是终端的第二个响应实际上是在第一个响应中,并且必须在其中发送密码。这是代码(我同意,我的解释有点模糊):

    String s="";
    Process p = Runtime.getRuntime().exec("p4 login");     
    BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));    
    char a=(char)in.read();
    while(a>0 && a<256)
    {

        a=(char)in.read();
        if(nb==14) new PrintWriter(p.getOutputStream(),true).println(password); 
        if(nb>16) s=s+a;
        nb++;
    }
    if(s.startsWith("User")) loggedIn=true;
    else loggedIn=false;
于 2012-04-30T11:07:19.463 回答
0

为了与一个进程通信,你不需要启动另一个进程,而是写入它的标准输入。实际上那里有代码试图做这样的事情。已sendLoginCommand返回创建的进程;删除所有代码sendPassword,实际上删除整个方法。在您的主代码中,将您的密码写入进程的输出流。所以我要说的是

new PrintWriter(sendLoginCommand().getOutputStream()).println(password);
于 2012-04-25T13:02:12.497 回答
0

作为旁注,我强烈建议使用一个预先打包的库,该库已经封装了有关 Java 中进程通信的所有技术内容。

一个很好的库是commons-exec ( http://commons.apache.org/exec/

它带有命令行助手、读取 sysout/syserr 输出的后台线程、在给定时间后杀死进程的可选看门狗等等(它当然适用于几乎所有操作系统)。

于 2012-05-01T00:18:47.963 回答