java 命令执行转义 '|'
java command execution escapes '|'
我有执行系统命令的功能:
public String cmd(String s) {
String out = "";
try {
Runtime run = Runtime.getRuntime();
Process pr = run.exec(s.split(" "));
pr.waitFor();
BufferedReader buf = new BufferedReader(new InputStreamReader(pr.getInputStream()));
String line = "";
while ((line=buf.readLine())!=null) {
out+=line+"\n";
}
} catch(Exception e) {
e.printStackTrace();
}
return out;
}
命令经过:
cmd("nmap -sL -n 192.168.1.0/24 | awk '/Nmap scan report/{print $NF}'");
预期输出:
192.168.1.0
192.168.1.1
...
实际输出:
Starting Nmap 7.80 ( https://nmap.org ) at 2021-04-12 20:27 EET
Nmap scan report for 192.168.1.0 ...
管道由 shell 解释。它执行一个命令,然后将一个命令的输出传递给下一个命令。您可以在 Java 中模拟此操作,启动两个命令,然后将第一个程序的 OutputStream
泵送到第二个程序的 InputStream
。
或者,如果您不想这样做,您仍然可以调用类似“sh -c 'command1 | command2”的命令
类似的问题回答得很好:
- Using Java ProcessBuilder to Execute a Piped Command
To execute a pipeline, you have to invoke a shell, and then run your commands inside that shell.
Process p = new ProcessBuilder().command("bash", "-c", command).start();
bash
invokes a shell to execute your command and -c
means commands are read from string. So, you don't have to send the command as an array in ProcessBuilder
.
适合您的情况
String cmd(String command) {
ProcessBuilder builder = new ProcessBuilder();
builder.redirectErrorStream(true); // add stdErr to output
Process process = builder.command("bash", "-c", command).start();
StringBuilder processOutput = new StringBuilder(); // add lines easier
// try-with to auto-close resources
try (BufferedReader processOutputReader = new BufferedReader(new InputStreamReader(process.getInputStream()));) {
String readLine;
while ((readLine = processOutputReader.readLine()) != null) {
processOutput.append(readLine + System.lineSeparator()); // use system's line-break
}
process.waitFor();
}
return processOutput.toString().trim();
}
然后按预期调用:
cmd("nmap -sL -n 192.168.1.0/24 | awk '/Nmap scan report/{print $NF}'");
注意:我把它增强了一点
- 使用try-with-resources干净地处理资源
- 添加来自 StdErr
的输出
- 使用
StringBuilder
连接输出行
- 使用
System.lineSeparator
实现平台独立性 (Win/Mac/Linux/Unix)
灵感来自:
read the output from java exec
我有执行系统命令的功能:
public String cmd(String s) {
String out = "";
try {
Runtime run = Runtime.getRuntime();
Process pr = run.exec(s.split(" "));
pr.waitFor();
BufferedReader buf = new BufferedReader(new InputStreamReader(pr.getInputStream()));
String line = "";
while ((line=buf.readLine())!=null) {
out+=line+"\n";
}
} catch(Exception e) {
e.printStackTrace();
}
return out;
}
命令经过:
cmd("nmap -sL -n 192.168.1.0/24 | awk '/Nmap scan report/{print $NF}'");
预期输出:
192.168.1.0
192.168.1.1
...
实际输出:
Starting Nmap 7.80 ( https://nmap.org ) at 2021-04-12 20:27 EET
Nmap scan report for 192.168.1.0 ...
管道由 shell 解释。它执行一个命令,然后将一个命令的输出传递给下一个命令。您可以在 Java 中模拟此操作,启动两个命令,然后将第一个程序的 OutputStream
泵送到第二个程序的 InputStream
。
或者,如果您不想这样做,您仍然可以调用类似“sh -c 'command1 | command2”的命令
类似的问题回答得很好:
- Using Java ProcessBuilder to Execute a Piped Command
To execute a pipeline, you have to invoke a shell, and then run your commands inside that shell.
Process p = new ProcessBuilder().command("bash", "-c", command).start();
bash
invokes a shell to execute your command and-c
means commands are read from string. So, you don't have to send the command as an array inProcessBuilder
.
适合您的情况
String cmd(String command) {
ProcessBuilder builder = new ProcessBuilder();
builder.redirectErrorStream(true); // add stdErr to output
Process process = builder.command("bash", "-c", command).start();
StringBuilder processOutput = new StringBuilder(); // add lines easier
// try-with to auto-close resources
try (BufferedReader processOutputReader = new BufferedReader(new InputStreamReader(process.getInputStream()));) {
String readLine;
while ((readLine = processOutputReader.readLine()) != null) {
processOutput.append(readLine + System.lineSeparator()); // use system's line-break
}
process.waitFor();
}
return processOutput.toString().trim();
}
然后按预期调用:
cmd("nmap -sL -n 192.168.1.0/24 | awk '/Nmap scan report/{print $NF}'");
注意:我把它增强了一点
- 使用try-with-resources干净地处理资源
- 添加来自 StdErr 的输出
- 使用
StringBuilder
连接输出行 - 使用
System.lineSeparator
实现平台独立性 (Win/Mac/Linux/Unix)
灵感来自: read the output from java exec