天道酬勤,学无止境

如何杀死runtime.exec?(how to kill runtime.exec?)

问题

我在我的 jframe 中使用下面的代码,以便通过 java 程序执行 shell 脚本,但是当我实现另一种方法来停止运行进程时,该方法首先被 th 阻止,我无法停止我的程序。 所以我 msut 杀死新进程,问题是如何获取进程的 pid 以及如何将其置于后台,以便杀死它。

public static void execShellCmd(String cmd) {
    try {

        testPath = getPath();

        System.out.println(cmd);
        Runtime runtime = Runtime.getRuntime();
        process = runtime.exec(new String[] { "sh",
                testPath + "/install.sh", cmd, "&" });
        int exitValue = process.waitFor();
        value = exitValue;
        System.out.println("exit value: " + exitValue);
        BufferedReader buf = new BufferedReader(new InputStreamReader(
                process.getInputStream()));
        String line = "";
        BufferedWriter bufferedWriter = null;
        while ((line = buf.readLine()) != null) {
            System.out.println("exec response: " + line);
            log = line;
            writeToFile(line);
        }
    } catch (Exception e) {
        System.out.println(e);
    }
}
回答1

为此,您可以使用 java.util.concurrent 中存在的功能

在包含 UI 的现有类中,您必须添加类似于以下内容的内容:

//class variable to store the future of your task
private Future<?> taskFuture = null;

//to be called from button "Start" action handler
public void actionStart() {

  //don't double start, if there is one already running
  if(taskFuture == null || taskFuture.isDone()) {

    //create the new runnable instance, with the proper commands to execute
    MyShellExecutor ex = new MyShellExecutor(new String[] { "sh",testPath + "/install.sh", cmd, "&" });

    //we only need one additional Thread now, but this part can be tailored to fit different needs
    ExecutorService newThreadExecutor = Executors.newSingleThreadExecutor();

    //start the execution of the task, which will start execution of the shell command
    taskFuture = newThreadExecutor.submit(ex);
  }
}

//to be called from button "Stop" action handler
public void actionStop() {
  //if not already done, or cancelled, cancel it
  if(taskFuture !=null && !taskFuture.isDone()) {
    taskFuture.cancel(true);
  }
}

完成这项工作的主要组件是我命名为MyShellExecutorRunnable ,它看起来像这样:

public class MyShellExecutor implements Runnable {

    //stores the command to be executed
    private final String[] toExecute;

    public MyShellExecutor(String[] toExecute) {
        this.toExecute=toExecute;
    }

    public void run() {
        Runtime runtime = Runtime.getRuntime();
        Process process = null;

        try {
            process = runtime.exec(toExecute);

            int exitValue = process.waitFor();
            System.out.println("exit value: " + exitValue);
            BufferedReader buf = new BufferedReader(new InputStreamReader(process.getInputStream()));

            String line = "";
            while ((line = buf.readLine()) != null) {
                System.out.println("exec response: " + line);
                //do whatever you need to do
            }

        } catch (InterruptedException e) {
            //thread was interrupted.
            if(process!=null) { process.destroy(); }
            //reset interrupted flag
            Thread.currentThread().interrupt();

        } catch (Exception e) {
            //an other error occurred
            if(process!=null) { process.destroy(); }
        }

    }
}

注意:运行耗时操作时,一定不要在UI线程上进行。 这只会阻止用户,并不能提供良好的用户体验。 总是做一些可能让用户等待不同线程的事情。

推荐阅读:Java并发实践

回答2

如果您的“其他方法”可以访问原始exec返回的Process对象,那么您可以简单地调用process.destroy()来终止正在运行的进程。 您不需要知道本机 PID。 这是一个使用 SwingWorker 的或多或少的完整示例(可能有一些我忘记的 try/catch 块):

private Process runningProcess = null;

public static void execShellCmd(String cmd) {
    if(runningProcess != null) {
        // print some suitable warning about process already running
        return;
    }
    try {

        testPath = getPath();

        System.out.println(cmd);
        Runtime runtime = Runtime.getRuntime();
        runningProcess = runtime.exec(new String[] { "sh",
                testPath + "/install.sh", cmd });

        new SwingWorker<Integer, Void>() {
            protected Integer doInBackground() {
                // read process output first
                BufferedReader buf = new BufferedReader(new InputStreamReader(
                    process.getInputStream()));
                String line = "";
                while ((line = buf.readLine()) != null) {
                    System.out.println("exec response: " + line);
                    log = line;
                    writeToFile(line);
                }

                // only once we've run out of output can we call waitFor
                while(true) {
                    try {
                        return runningProcess.waitFor();
                    } catch(InterruptedException e) {
                        // do nothing, wait again
                    } finally {
                        Thread.interrupted();
                    }
                }
                return -1;
            }

            protected void done() {
                runningProcess = null;
            }
        }.execute();
    }
}

public static void stopProcess() {
    if(runningProcess != null) {
        runningProcess.destroy();
    }
}

只要execShellCmdstopProcess只从事件调度线程中调用,那么就不需要同步,因为对runningProcess字段的所有访问都发生在同一个线程上( SwingWorker的要点是doInBackground发生在工作线程上,但done运行在美国东部时间)。

标签

受限制的 HTML

  • 允许的HTML标签:<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • 自动断行和分段。
  • 网页和电子邮件地址自动转换为链接。

相关推荐
  • 使用Java杀死进程(Killing a process using Java)
    问题 我想知道如何“杀死”已启动的过程。 我知道Process API,但是不确定,是否可以使用它来杀死已经运行的进程,例如firefox.exe等。如果可以使用Process API,请您指向我正确的方向? 如果没有,还有哪些其他可用选项? 谢谢。 回答1 如果您从Java应用程序中使用来启动进程(例如,通过调用Runtime.exec()或ProcessBuilder.start() ),那么您将对其具有有效的Process引用,并且可以在Process类中调用destroy()方法杀死那个特定的过程。 但是请注意,如果您调用的流程创建了新的子流程,则这些子流程可能不会终止(请参见http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4770092)。 另一方面,如果您想杀死外部进程(您不是从Java应用程序生成的),那么您可以做的一件事就是调用允许您执行此操作的O / S实用程序。 例如,您可以在Unix / Linux下在kill命令上尝试Runtime.exec()并检查返回值以确保应用程序是否被杀死(0表示成功,-1表示错误)。 但这当然会使您的应用程序平台依赖。 回答2 在Windows上,您可以使用此命令。 taskkill /F /IM <processname>.exe 要强行杀死它,您可以使用; Runtime
  • 如何在 Windows 上找到正在运行的 Java 进程的进程 ID? 以及如何单独杀死进程?(How to find the process id of a running Java process on Windows? And how to kill the process alone?)
    问题 我想在 Windows 中ps -aux特定的 Java 进程,就像在 Linux 中一样( ps -aux获取 processid,然后kill processid以ps -aux进程)。 回答1 您可以使用 JDK 中包含的jps实用程序来查找 Java 进程的进程 ID。 输出将显示可执行 JAR 文件的名称或主类的名称。 然后使用 Windows 任务管理器终止该进程。 如果您想在命令行上执行此操作,请使用 TASKKILL /PID %PID% 回答2 您还可以使用任务管理器找到 Java 程序的 PID。 您启用PID和命令行列View -> Select Columns然后能够找到正确的进程。 你的结果将是这样的: 回答3 设置 jdk 的路径后使用JPS 。然后您可以通过任务管理器轻松杀死它 JPS会给你所有的java进程 回答4 即使有多个 jar 实例正在运行,这也能工作 wmic Path win32_process Where "CommandLine Like '%yourname.jar%'" Call Terminate 回答5 我找到的解决方案非常简单。 使用 Window 的 WMIC 和 Java 的运行时定位并终止进程。 第 1 部分:您需要将某种标识符放入应用程序的启动命令行中。 例如: String id = "com.domain
  • 在一段时间后杀死由 exec() 启动的进程并将帧存储在数组中(Kill a process started by exec() after some duration and store frames in an array)
    问题 首先让我说我对 Java 完全陌生。 我来自 PHP 背景,但碰巧我的一项 PHP 任务需要转换为 Java。 任务是使用 ffmpeg 将视频分割成帧,然后处理这些帧。 我已经在 PHP 中完成了这个过程。 现在我可以将其转换为 Java。 我浏览了一些教程并涵盖了基础知识(使用 IDE、运行 Java 程序等)。 为此,我正在使用 Eclipse。 到目前为止,我已经设法通过使用 java 程序来启动 ffmpeg public static void main(String[] args) throws IOException { String livestream = "D:/video.mpg"; String folderpth = "D:/frames"; String cmd="D:/ffmpeg/bin/ffmpeg.exe -i "+ livestream +" -r 10 "+folderpth+"/image%d.jpg"; //System.out.println(cmd); Runtime r = Runtime.getRuntime(); Process p = r.exec(cmd); // this starts creating frames // and stores them on local disk // any way to
  • 用 Java 重启 Tomcat(Restart Tomcat with Java)
    问题 我需要从 Java 代码重新启动 tomcat。 例如,如果某个查询在一段时间内没有执行,那么它会自动重启 tomcat。 我已经尝试了以下关闭和启动代码,但是当我们关闭 tomcat 时,java 代码将无法运行并且 tomcat 无法启动。 注意:- 我正在从应用程序运行此代码并重新启动同一应用程序正在使用的同一个 tomact。 按照代码 try { PreparedStatement.setQueryTimeout(10); rs = PreparedStatement.executeQuery(); } catch (SQLException ex) { System.out.println("IN CATCH BLOCK FOR THE REFRESH INVOICE"); String shutcommand = "killall java"; Process shutchild = Runtime.getRuntime().exec(shutcommand); System.out.println("JAVA PROCESS KILLED"); String locationCommand = "cd /root/cluster/tomcat6/bin"; Process locationChild = Runtime.getRuntime().exec
  • 线程启动的运行进程不会破坏(Java)(Thread-launched running processes won't destroy (Java))
    问题 启动多个线程并让每个 exec() 然后 destroy() 一个正在运行的 java 进程会导致某些进程没有被销毁并在程序退出后仍在运行。 这是一些重现问题的代码。 我注意到你启动的线程越多,存活的进程就越多。 在 destroy() 之前休眠越多,存活的进程就越少。 (我以 InfiniteLoop 为例。任何正在运行的进程都可以。) 编辑:错误已报告给 Oracle,等待答复。 随意分享有关该主题的任何知识/实验。 for(int i = 0; i < 100; i++) { new Thread(new Runnable() { public void run() { try { Process p = Runtime.getRuntime().exec(new String[]{"java", "InfiniteLoop"}); Thread.sleep(1); p.destroy(); }catch(IOException | InterruptedException e){e.printStackTrace();} } }).start(); } 回答1 使用p.waitFor(); 在p.destroy();之前p.destroy(); , 这将确保完成先前的过程。 我认为 p.destroy 命令比exec()命令执行操作更早被调用。 因此它变得毫无用处。
  • 如何解决调用Runtime#exec()的“ java.io.IOException:错误= 12,无法分配内存”?(How to solve “java.io.IOException: error=12, Cannot allocate memory” calling Runtime#exec()?)
    问题 在我的系统上,我无法运行启动流程的简单Java应用程序。 我不知道该怎么解决。 您能给我一些解决方法的提示吗? 该程序是: [root@newton sisma-acquirer]# cat prova.java import java.io.IOException; public class prova { public static void main(String[] args) throws IOException { Runtime.getRuntime().exec("ls"); } } 结果是: [root@newton sisma-acquirer]# javac prova.java && java -cp . prova Exception in thread "main" java.io.IOException: Cannot run program "ls": java.io.IOException: error=12, Cannot allocate memory at java.lang.ProcessBuilder.start(ProcessBuilder.java:474) at java.lang.Runtime.exec(Runtime.java:610) at java.lang.Runtime.exec(Runtime.java:448
  • how to kill runtime.exec?
    I use the code below , in my jframe in order to execute a shell script via java program, but when i implement an other method to stop runing process, this method is blocked by th first and i can't stop my program. So i msut kill the new process, the problem is how to get the pid of the process and how to put it in background, in order to kill it. public static void execShellCmd(String cmd) { try { testPath = getPath(); System.out.println(cmd); Runtime runtime = Runtime.getRuntime(); process = runtime.exec(new String[] { "sh", testPath + "/install.sh", cmd, "&" }); int exitValue = process
  • 如何从Java程序启动完全独立的进程?(How do I launch a completely independent process from a Java program?)
    问题 我正在开发一个用Java编写的程序,对于某些操作,它使用用户配置的命令行启动外部程序。 当前,它使用Runtime.exec()并且不保留Process引用(启动的程序是文本编辑器或归档实用程序,因此不需要系统输入/输出/错误流)。 但是,这有一个小问题,即当Java程序退出时,直到所有启动的程序都退出后,它才真正退出。 如果启动的程序完全独立于启动它们的JVM,我将更喜欢它。 目标操作系统是多个,最低要求是Windows,Linux和Mac,但是真正需要的是带有JVM的任何GUI系统(因此,用户可以配置实际的命令行)。 有谁知道如何使启动的程序完全独立于JVM执行? 编辑以回应评论 启动代码如下。 该代码可以启动位于特定行和列的编辑器,也可以启动档案查看器。 在配置的命令行中,将引号值视为ECMA-262编码,然后对其进行解码,并去除引号以形成所需的exec参数。 启动发生在EDT上。 static Throwable launch(String cmd, File fil, int lin, int col) throws Throwable { String frs[][]={ { "$FILE$" ,fil.getAbsolutePath().replace('\\','/') }, { "$LINE$" ,(lin>0 ? Integer.toString(lin)
  • 当父进程退出时,如何使子进程退出?(How can I cause a child process to exit when the parent does?)
    问题 我正在使用ProcessBuilder启动子进程,并且如果父进程确实需要退出子进程。 在正常情况下,我的代码可以正确阻止孩子。 但是,如果我导致操作系统杀死父进程,则子进程将继续运行。 有什么方法可以将子进程“绑定”到父进程,以便在父进程被杀死时退出? 类似问题: 父母退出后如何使子进程死亡? 使用fork()创建的子进程会在父进程被杀死时自动被杀死吗? 回答1 子进程与其父进程之间没有联系。 他们可能彼此知道进程ID,但是它们之间没有硬连接。 您所说的是一个孤儿过程。 这是操作系统级别的问题。 意味着任何解决方案都可能取决于平台。 我唯一能想到的就是让孩子定期检查其父母的状态,如果父母关闭了就退出。 我认为这不是那么可靠。 回答2 虽然您无法防止硬中断(例如Unix上的SIGKILL),但是可以防止导致父进程关闭(例如SIGINT)并清理子进程的其他信号。 您可以通过使用关闭挂钩来完成此任务:请参阅Runtime#addShutdownHook,以及此处的相关SO问题。 您的代码可能看起来像这样: String[] command; final Process childProcess = new ProcessBuilder(command).start(); Thread closeChildThread = new Thread() { public void run
  • Java调用外部程序(如Windows下的Exe,或Linux的Shell)
    序言 java程序可以调用Jvm外部的一些应用程序来完成一些功能.目前基于JDK1.8来做实验~ 目前java有如下两种方式来调用其它程序, Runtime和ProcessBulider提供了不同的方式来启动程序,设置启动参数、环境变量和工作目录。(这些都能设置,就是帮你找到外部可执行文件的位置与启动变量,具体怎么执行,可以查看Runtime和ProcessBuilder的构造方法,里面有设置) 但是这两种方法都会返回一个用于管理操作系统进程的Process对象。另外两者的启动差别不是很大.最终生成的Process子进程是独立于Jvm之外的进程,就算没有对象应用指向它,它也不会被GC关闭或者释放. 在用Runtime.getRuntime().exec()或ProcessBuilder(array).start()创建子进程Process之后,一定要及时取走子进程的输出信息和错误信息,否则输出信息流和错误信息流很可能因为信息太多导致被填满,最终导致子进程阻塞住,然后执行不下去。 这么来说其实重要的是Process的使用. Runtime的exec()方法,并返回一个Process对象ProcessBuilder的start()方法,并返回一个Process对象 Runtime Runtime类是Java程序的运行时环境。不能new出一个Runtime对象
  • Java runtime.exec does not execute correctly
    I am getting an exe-File, which I have to execute using Java (Version 6) on Windows Server 2008 R2. Now there is s problem I do not really understand. When executing the file with the commandline "C:\test.exe param1 param2" it works correctly, but when I execute the file with Process proc = Runtime.getRuntime().exec("C:\\test.exe param1 param2"); proc.waitFor(); I can see the test.exe in the windows task manager and it starts running (it creates a log which states that), but then it simply doesn't do anything anymore. The test.exe endlessly runs with 0% and I have to kill the process manually
  • 如何用Java创建流程(How to create a process in Java [closed])
    问题 关闭。 此问题不符合堆栈溢出准则。 它当前不接受答案。 想要改善这个问题吗? 更新问题,使它成为Stack Overflow的主题。 4年前关闭。 改善这个问题 我想在我的应用程序中创建一个过程。 但是,从Java的API环顾四周之后,我仍然不太了解它。 基本上,我想创建一个多进程应用程序。 但是新过程是我的应用程序中的一类。 我知道有些人可能会问为什么不创建线程? 因为该类正在调用Matlab代码,所以问题出在这里,而Java类在这里 有什么办法吗? 回答1 只有一种方法可以在Java中创建进程,即Runtime.exec()-基本上,它允许您像通过命令行界面一样启动新的JVM。 回答2 也许java.lang.Process可以在这里帮助.. ProcessBuilder.start()和Runtime.exec方法创建本机进程,并返回Process子类的实例,该实例可用于控制该进程并获取有关该进程的信息。 Process类提供了以下方法:执行来自过程的输入,执行到过程的输出,等待过程完成,检查过程的退出状态以及销毁(杀死)过程。 回答3 如果需要更细粒度的控制,则可以使用ProcessBuilder-此类允许您设置环境变量并配置项目的管道( stdout , in , err )。 配置ProcessBuilder#start()
  • Android JNI 原生 C 函数调用杀死活动(Android JNI native C function call kills activity)
    问题 什么有效:我有一个运行 TUN/TAP 服务的 ac 可执行文件,以及两个在终端中运行良好的 shell 脚本(用于配置“ip route”和“iptables”),都以 root 身份运行。 什么不起作用:我正在尝试创建一个 Android 应用程序以在按下按钮后运行 c 可执行文件和 shell 脚本。 我最初这样做是为了让 onClick 使用 processBuilder 创建一个进程,如下所示: final Button button1 = ... ... public void onClick(View v) { String ip_address = edIPAddress.getText().toString(); Process process; try { process = new ProcessBuilder() .command("/system/bin/su", "-c", "/data/tuntapserv/armeabi/mytunserv " + ip_address) .redirectErrorStream(true) .start(); InputStream in = process.getInputStream(); OutputStream out = process.getOutputStream(); pOutput
  • Runtime.exec() bug: hangs without providing a Process object
    Whether I use this: process = Runtime.getRuntime().exec("logcat -d time"); or that: process = new ProcessBuilder() .command("logcat", "-d", "time") .redirectErrorStream(true) .start(); I get the same results: it often hangs within the exec() or start() call, no matter what I tried to do! The thread running this cannot even be interrupted with Thread.interrupt()! The child process is definitely started and if killed the above commands return. These calls may fail on first attempt, so THERE IS NO WAY TO READ THEIR OUTPUT! I can also use a simple "su -c kill xxx" command line, same result! EDIT
  • 需要有关流程的帮助(need help about process)
    问题 当我启动进程时,如process= Runtime.getRuntime().exec("gnome-terminal"); ,它开始 shell 执行,我想停止 shell 执行并想从进程重定向 I/O,有人能告诉我如何做到这一点吗? 我的代码是: public void start_process() { try { process= Runtime.getRuntime().exec("bash"); pw= new PrintWriter(process.getOutputStream(),true); br=new BufferedReader(new InputStreamReader(process.getInputStream())); err=new BufferedReader(new InputStreamReader(process.getErrorStream())); } catch (Exception ioe) { System.out.println("IO Exception-> " + ioe); } } public void execution_command() { if(check==2) { try { boolean flag=thread.isAlive(); if(flag==true) thread.stop()
  • 如何将标准输入重定向到Java Runtime.exec?(how to redirect stdin to java Runtime.exec?)
    问题 我想使用Java的Runtime.exec方法执行一些sql脚本。 我打算调用mysql.exe / mysql.sh并将脚本文件重定向到此过程。 在命令提示符下,我可以运行命令 <mysqInstallDir\/bin\mysql.exe -u <userName> -p <password> < scripts\create_tables.sql 我可以使用Runtime.exec调用mysql.exe,但是如何将数据从sql文件重定向到mysql.exe? 我阅读了http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html?page=4中的文章,并使用StreamGobbler机制获取错误并输出流。 没问题。 问题出在使用BufferedReader读取文件“ scripts \ create_tables.sql”并将内容传递给prcess的输出流。 我期望进程将数据传递到mysql.exe。 但是我看到仅从此sql文件中读取第一行。 OutputStream outputstream = proc.getOutputStream(); OutputStreamWriter outputstreamwriter = new OutputStreamWriter(outputstream)
  • 如何使管道与Runtime.exec()一起使用?(How to make pipes work with Runtime.exec()?)
    问题 考虑以下代码: String commandf = "ls /etc | grep release"; try { // Execute the command and wait for it to complete Process child = Runtime.getRuntime().exec(commandf); child.waitFor(); // Print the first 16 bytes of its output InputStream i = child.getInputStream(); byte[] b = new byte[16]; i.read(b, 0, b.length); System.out.println(new String(b)); } catch (IOException e) { e.printStackTrace(); System.exit(-1); } 该程序的输出为: /etc: adduser.co 当然,当我从外壳运行时,它可以按预期工作: poundifdef@parker:~/rabbit_test$ ls /etc | grep release lsb-release 互联网告诉我,由于管道行为不是跨平台的,因此在生产Java的Java工厂工作的才华横溢的人不能保证管道能正常工作。 我怎样才能做到这一点?
  • 如何检查 Runtime.exec(cmd) 是否完成(how can check Runtime.exec(cmd) is completed or not)
    问题 如何检查 Runtime.exec(cmd) 是否完成? 它正在运行,但如何检查命令是否在 java 程序中执行? 如果我使用进程来检查,那么它正在阻塞当前线程。 如果我停止运行程序,则 Runtime.exec(cmd) 正在执行。 我应该怎么办? 回答1 Process 实例可以通过其 InputStream 和 Outpustream 帮助您操纵运行时的执行。 流程实例有一个waitFor()方法,可以让当前的Thread等待子流程的终止。 要控制流程的完成,您还可以获取运行时的exitValue ,但这取决于流程返回的内容。 下面是一个简单的例子,说明如何使用waitFor并获取进程结果(注意,这将阻塞您当前的线程,直到进程结束)。 public int runCommand(String command) throws IOException { int returnValue = -1; try { Process process = Runtime.getRuntime().exec( command ); process.waitFor(); returnValue = process.exitValue(); } catch (InterruptedException e) { e.printStackTrace(); } return
  • 使用 Java 的 Google 云存储 gsutil 工具(Google cloud storage gsutil tool with Java)
    问题 如果我们每天有大约 30G 的文件(从 50MB 到 4GB)需要上传到 Google Cloud Storage,根据 google docs,gsutil 可能是唯一合适的选择,不是吗? 我想通过 Java 调用 gsutil 命令,现在下面的代码可以工作了。 但是如果我删除那个while循环,程序将在runtime.exec(command)之后立即停止,但python进程已启动但没有上传,它很快就会被杀死。 我想知道为什么。 我从 sterr 流中读取的原因是受到 Pipe gsutil output to file 的启发 我决定 gsutil 是否通过 read util 完成其状态输出的最后一行的执行,但这是一种可靠的方法吗? 有没有更好的方法来检测 gsutil 执行是否以 Java 结束? String command="python c:/gsutil/gsutil.py cp C:/SFC_Data/gps.txt" + " gs://getest/gps.txt"; try { Process process = Runtime.getRuntime().exec(command); System.out.println("the output stream is "+process.getErrorStream()); BufferedReader
  • 如何清理 Runtime.exec() 中使用的用户输入?(How to sanitize user input used in Runtime.exec()?)
    问题 我需要通过命令行调用自定义脚本,脚本需要很少的参数并在 Linux 机器上调用。 当前版本容易出现各种shell注入,如何清理用户给出的参数? 参数包括登录名和路径(Unix 或 Windows 路径),用户应该能够输入任何可能的路径(路径指的是用户服务器上的远程路径)。 现在的代码看起来像这样: Process process = Runtime.getRuntime().exec("myscript " + login + " " + path); 回答1 从这个答案中,改用ProcessBuilder : ProcessBuilder pb = new ProcessBuilder("myscript", login, path); 这应该可以防止外壳注入。 如果路径仅指他们自己系统上的路径,那么路径注入应该不是问题: 路径是指用户服务器上的远程路径 风险在于服务器是否以某种方式联系“路径”,这从您的问题中不清楚。 它是什么类型的路径? 一个 URL 路径,一个 Samba 共享? 您可能需要保护它以防止服务器端请求伪造。 这涉及验证用户输入以检查它是否指的是外部服务器,而不是您自己网络内部的服务器。 回答2 验证路径的一种方法是使用FileSystem方法getPath()构造一个Path对象,然后通过toString() (或toAbsolutePath()