bash 来自java的bash unix processbuilder未运行

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14703271/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 04:28:10  来源:igfitidea点击:

bash unix processbuilder from java not running

javabashunixservletsprocessbuilder

提问by abierto

I want to execute a simple Unix command from my Java servlet: what I need to do is a simple echo write to file like this one:

我想从我的 Java servlet 执行一个简单的 Unix 命令:我需要做的是一个简单的回显写入文件,如下所示:

echo HELLO > myfile.txt

What I'm doing in my servlet is:

我在我的 servlet 中做的是:

import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ServletAutorecovery extends HttpServlet {
    protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        try {
            ProcessBuilder pb = new ProcessBuilder("/usr/bin/bash", "-c", "echo HELLO > ../webapps/test/myfile.txt");
            pb.start();
        } finally { 
        out.close();
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        processRequest(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        processRequest(request, response);
    }
}

My problem is: this code section is not giving me any errors, but nothing happens. After I executed my servlet, the file has not being created, and of course, nothing is written in it.

我的问题是:这个代码部分没有给我任何错误,但没有任何反应。在我执行了我的 servlet 之后,文件还没有被创建,当然,里面什么也没有写。

What am I doing wrong?

我究竟做错了什么?

EDIT1: added full path to pb command.

EDIT1:添加了 pb 命令的完整路径。

EDIT2: bashis in the path /usr/bin/bash, 100% sure of it.

EDIT2:bash在路径中/usr/bin/bash,100% 确定。

EDIT3: added SSCCE.

EDIT3:添加了 SSCCE。

回答by Ian Roberts

First, are you sure bash is definitely at /usr/bin? Second, you probably need to tell the ProcessBuilder what directory it should use as the cwd when running the process, otherwise it will try and create myfile.txt in whatever is the current directory of the servlet container, typically somewhere you don't have write access. And thirdly, when you run a process from java the output of the process is passed back to java via input streams on the process object, it doesn't go straight to stdout, so you need to read the streams to see the result

首先,你确定 bash 肯定在/usr/bin?其次,您可能需要告诉 ProcessBuilder 在运行进程时它应该使用哪个目录作为 cwd,否则它会尝试在 servlet 容器的当前目录中创建 myfile.txt,通常是在您没有写的地方使用权。第三,当您从 java 运行进程时,该进程的输出通过进程对象上的输入流传递回 java,它不会直接进入 stdout,因此您需要读取流以查看结果

ProcessBuilder pb = new ProcessBuilder("/usr/bin/bash", "-c", "echo HELLO > myfile.txt");
pb.directory(...);
pb.redirectErrorStream(true);
Process p = pb.start();
IOUtils.copy(p.getInputStream(), System.out);
p.waitFor();

回答by MrSimpleMind

String echo = "echo 'hello' > myfile.txt";
ProcessBuilder pb = new ProcessBuilder("/usr/bin/bash", "-c", echo);
pb.start();

回答by Aaron Digulla

Check your error handling; you're probably swallowing an exception somewhere because there is no bashin /usr/bin, so you're getting a "file not found" exception (or similar).

检查您的错误处理;您可能正在某处吞下异常,因为没有bashin /usr/bin,因此您会收到“找不到文件”异常(或类似)。

Try "/bin/bash"instead. The rest should work.

试试吧"/bin/bash"。其余的应该工作。

Also note that relative paths won't work after you deploy you app since it will be relative to the process running the Java VM which isn't what you expect, want or could use. Ask your ServletContextfor a path with getRealPath()

另请注意,在部署应用程序后,相对路径将不起作用,因为它将与运行 Java VM 的进程相关,这不是您期望、想要或可以使用的。询问你ServletContext的路径getRealPath()