如何从Java程序执行本机 Shell 命令?
外壳命令是我们可以使用键盘和命令行或外壳而不是图形用户界面触发的命令。通常,我们会手动触发 shell 命令。但是,在某些情况下,这需要通过Java以编程方式完成。
Java支持使用两个类运行本机 shell 命令:RunTime 和 ProcessBuilder。使用这些类并从Java程序内部运行 shell 命令的主要缺点是Java失去了可移植性。
失去便携性意味着什么?
Java遵循“一次编译,随处运行”的原则。这意味着在一个操作系统上编写和编译的Java程序可以在任何其他操作系统上运行而无需进行任何更改。
当我们使用 ProcessBuilder 或 Runtime 类运行 Native shell 命令时,我们使Java程序依赖于底层操作系统。例如,一个专门运行 Linux shell 命令的Java程序不能在 Windows 机器上按原样运行,主要是因为 Windows 具有不同的文件夹结构和 shell 命令。
例子:
前三个示例将着眼于实现 ProcessBuilder 类以在Java运行 shell 命令。以下示例适用于 RunTime 类。
示例 1:失去便携性。
这个例子展示了如果我们在 Windows 操作系统上执行一个适用于 Linux/Unix 操作系统的Java程序会发生什么。
Java
// if we execute a Java program meant for the Linux/Unix
// operating system on a Windows operating system
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
public class ShellCommandRunner4 {
public static void main(String[] args)
{
try {
System.out.println(
System.getProperty("os.name"));
System.out.println();
// This process cannot be run on Windows. So the
// program will throw an exception.
ProcessBuilder pb
= new ProcessBuilder("sh", "-c", "ls");
// Exception thrown here because folder
// structure of Windows and Linux are different.
pb.directory(
new File(System.getProperty("user.home")));
// It will throw and exception
Process process = pb.start();
StringBuilder output = new StringBuilder();
BufferedReader reader
= new BufferedReader(new InputStreamReader(
process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
output.append(line + "\n");
}
int exitVal = process.waitFor();
if (exitVal == 0) {
System.out.println(
"**************************** The Output is ******************************");
System.out.println(output);
System.exit(0);
}
}
catch (IOException e) {
e.printStackTrace();
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Java
// Run a simple Windows shell command
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
public class ShellCommandRunner {
public static void main(String[] args)
{
ProcessBuilder processBuilder
= new ProcessBuilder();
List builderList = new ArrayList<>();
// add the list of commands to a list
builderList.add("cmd.exe");
builderList.add("/C");
builderList.add("tasklist | findstr chrome");
try {
// Using the list , trigger the command
processBuilder.command(builderList);
Process process = processBuilder.start();
// To read the output list
BufferedReader reader
= new BufferedReader(new InputStreamReader(
process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
int exitCode = process.waitFor();
System.out.println("\nExited with error code : "
+ exitCode);
}
catch (IOException e) {
e.printStackTrace();
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Java
// Run a simple .bat program in the Java console
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
public class ShellCommandRunner3 {
public static void main(String[] args)
{
try {
// File location for the bat script
File dir = new File("D:\\bat_scripts");
// Command to run the bat file in the same
// console
ProcessBuilder pb = new ProcessBuilder(
"cmd.exe", "/C", "sysinfo.bat");
pb.directory(dir);
Process process = pb.start();
StringBuilder output = new StringBuilder();
BufferedReader reader
= new BufferedReader(new InputStreamReader(
process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
output.append(line + "\n");
}
int exitVal = process.waitFor();
if (exitVal == 0) {
System.out.println(
"**************************** The Output is ******************************");
System.out.println(output);
System.exit(0);
}
}
catch (IOException e) {
e.printStackTrace();
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Java
// Run a simple command using the RunTime class
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
public class ShellCommandRunner2 {
public static void main(String[] args)
{
try {
Process process
= Runtime.getRuntime().exec("where java");
StringBuilder output = new StringBuilder();
BufferedReader reader
= new BufferedReader(new InputStreamReader(
process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
output.append(line + "\n");
}
int exitVal = process.waitFor();
if (exitVal == 0) {
System.out.println(
"**************************** The Output is ******************************");
System.out.println(output);
System.exit(0);
}
}
catch (IOException e) {
e.printStackTrace();
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
示例 2:运行简单的 shell 命令
此示例显示如何运行简单的 Windows shell 命令。我们使用列表来构建命令,然后使用 ProcessBuilder 类的“start”方法执行它们。程序运行命令从机器中运行的任务列表中查找 chrome 浏览器进程。
Java
// Run a simple Windows shell command
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
public class ShellCommandRunner {
public static void main(String[] args)
{
ProcessBuilder processBuilder
= new ProcessBuilder();
List builderList = new ArrayList<>();
// add the list of commands to a list
builderList.add("cmd.exe");
builderList.add("/C");
builderList.add("tasklist | findstr chrome");
try {
// Using the list , trigger the command
processBuilder.command(builderList);
Process process = processBuilder.start();
// To read the output list
BufferedReader reader
= new BufferedReader(new InputStreamReader(
process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
int exitCode = process.waitFor();
System.out.println("\nExited with error code : "
+ exitCode);
}
catch (IOException e) {
e.printStackTrace();
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
示例 3:运行 bat 文件
此示例显示如何在Java控制台中运行简单的 .bat 程序。 .bat 文件显示 Windows 系统信息。
Java
// Run a simple .bat program in the Java console
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
public class ShellCommandRunner3 {
public static void main(String[] args)
{
try {
// File location for the bat script
File dir = new File("D:\\bat_scripts");
// Command to run the bat file in the same
// console
ProcessBuilder pb = new ProcessBuilder(
"cmd.exe", "/C", "sysinfo.bat");
pb.directory(dir);
Process process = pb.start();
StringBuilder output = new StringBuilder();
BufferedReader reader
= new BufferedReader(new InputStreamReader(
process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
output.append(line + "\n");
}
int exitVal = process.waitFor();
if (exitVal == 0) {
System.out.println(
"**************************** The Output is ******************************");
System.out.println(output);
System.exit(0);
}
}
catch (IOException e) {
e.printStackTrace();
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
示例 4:使用 RunTime 类运行 shell 命令。
此示例显示如何使用 RunTime 类运行简单命令。我们使用 Runtime 类的 exec() 方法。
Java
// Run a simple command using the RunTime class
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
public class ShellCommandRunner2 {
public static void main(String[] args)
{
try {
Process process
= Runtime.getRuntime().exec("where java");
StringBuilder output = new StringBuilder();
BufferedReader reader
= new BufferedReader(new InputStreamReader(
process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
output.append(line + "\n");
}
int exitVal = process.waitFor();
if (exitVal == 0) {
System.out.println(
"**************************** The Output is ******************************");
System.out.println(output);
System.exit(0);
}
}
catch (IOException e) {
e.printStackTrace();
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}