简体   繁体   English

使用Java依次执行两个或多个Shell命令

[英]Execute two or more shell commands sequentially using Java

I want to execute telnet and msh in a shell on Linux one after another sequentially. 我想依次在Linux上的Shell中依次执行telnetmsh I am able to execute telnet command, but not msh command using the below code in Java: 我可以使用以下Java代码执行telnet命令,但不能执行msh命令:

List<String> commands = new ArrayList<String>();
commands.add("/bin/bash");
commands.add("-c");
commands.add("telnet 10.x.x.x 1234");
commands.add("msh");
ProcessBuilder pb = new ProcessBuilder(commands);
pb.directory(new File("/home/user"));
pb.redirectErrorStream(true);
Process process = pb.start();

// Read output
StringBuilder out = new StringBuilder();
BufferedReader br = new BufferedReader(new InputStreamReader(
    process.getInputStream()));
String line = null, previous = null;
while ((line = br.readLine()) != null) {
    if (!line.equals(previous)) {
        previous = line;
        out.append(line).append('\n');
        System.out.println(line);
    }
}

// Check result
if (process.waitFor() == 0) {
    System.out.println("Success executing telnet command!");
    System.exit(0);
}

System.err.println(commands);
System.err.println(out.toString());
System.exit(1);

Any help on this is highly appreciated. 对此,我们将给予任何帮助。

You should have two different commands to execute both in sequence like below:- 您应该有两个不同的命令来依次执行这两个命令,如下所示:-

 String[] command_telnet ={"\path\to\telnet", "10.x.x.x 1234"};
 String[] command_msh ={"\path\to\msh", "parameter"};

 ProcessBuilder pb_telnet = new ProcessBuilder(commands);
 pb_telnet.directory(new File("/home/user/telnet_output.txt"));
 pb_telnet.redirectErrorStream(true);
 Process process_tel = pb_telnet.start();

Do the same for command_msh . command_msh执行相同的操作。 This approach will be easy for you to debug as you will get the command output in /home/user/msh_output.txt 您可以轻松调试该方法,因为您将在/home/user/msh_output.txt获得命令输出

What you are currently having Java execute is the following (more or less; the following can be executed in a Shell, Java directly invokes a process): 您当前正在执行的Java是以下内容(或多或少;以下内容可以在Shell中执行,Java直接调用进程):

/bin/bash -c 'telnet 10.x.x.x 1234' 'msh'

This leads to Bash executing telnet, because that is the argument to the -c flag, and the msh argument will be ignored: Bash doesn't know what to do with it. 这导致Bash执行telnet,因为这是-c标志的参数,而msh参数将被忽略:Bash不知道如何处理。

There are two possible solutions. 有两种可能的解决方案。

Solution 1: let Bash execute the two commands sequentially. 解决方案1:让Bash依次执行两个命令。
For this to work, you want to execute something along the following lines 为此,您需要执行以下几行

/bin/bash -c 'telnet 10.x.x.x 1234; msh'

which translates to you having to merge the last two strings in your commands list. 这意味着您必须合并commands列表中的最后两个字符串。 For example, 例如,

commands.add("telnet 10.x.x.x 1234; msh");

Instead of using ; 代替使用; you can also use && . 您也可以使用&& See Unix.SE for more details. 有关更多详细信息,请参见Unix.SE。

Disadvantage: Bash will let you know the exit code of the last process only. 缺点:Bash仅会让您知道最后一个进程的退出代码。 In the case of using && , having the first command fail will not even execute the second one. 在使用&&的情况下,使第一个命令失败甚至不会执行第二个命令。

Solution 2: create a separate process in Java for each. 解决方案2:分别使用Java创建一个单独的进程。
For this solution, you'll essentially have to repeat all your code for the invocation of msh. 对于此解决方案,您基本上必须重复所有代码以调用msh。 I'd recommend wrapping it in a function if you go this route. 如果您采用这种方法,建议您将其包装在函数中。 Simply use {"/bin/bash", "-c", "telnet 10.xxx 1234"} as the list of commands for one invocation, and {"/bin/bash", "-c", "msh"} for the other invocation. 只需使用{"/bin/bash", "-c", "telnet 10.xxx 1234"}作为一次调用的commands列表,然后使用{"/bin/bash", "-c", "msh"}用于其他调用。

Advantage is that you have more control in your Java program, instead of having Bash handle things. 优点是您可以在Java程序中拥有更多控制权,而不是让Bash处理事情。 Disadvantage is you starting two separate processes, but Bash might do that under the hood anyway. 缺点是您要启动两个单独的过程,但是Bash仍可能在后台进行此操作。


Side remark: you can directly execute telnet and msh without invoking Bash and telling it to run telnet or msh for you. 旁注:您可以直接执行telnet和msh,而无需调用Bash并告诉它为您运行telnet或msh。 That might be even nicer, and more efficient. 这样可能会更好,更有效。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM