4

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:

echo HELLO > myfile.txt

What I'm doing in my servlet is:

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.

What am I doing wrong?

EDIT1: added full path to pb command.

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

EDIT3: added SSCCE.

10
  • 1
    where do you expect the myfile.txt to be ? where do you look/search ? try to write the file to a path you know. for example /tmp/myfile.txt Commented Feb 5, 2013 at 8:47
  • I am actually writing it in my project folder, ../webapps/test/myfile.txt. Commented Feb 5, 2013 at 8:50
  • Did you try with Runtime ? Runtime.getRuntime().exec("echo HELLO > myfile.txt"); Commented Feb 5, 2013 at 8:52
  • Tried this: ProcessBuilder pb = new ProcessBuilder("bash", "-c", "echo HELLO > myfile.txt"); Commented Feb 5, 2013 at 8:55
  • 1
    For better help sooner, post an SSCCE. Commented Feb 5, 2013 at 9:14

3 Answers 3

8

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

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();
Sign up to request clarification or add additional context in comments.

6 Comments

Sorry, but in pb.directory(...) what directory should I write? The output one, where I want myfile.txt to be in? I also have problem using IOUtils, even if I added import java.lang.Object;.
.. 4) You might as well break "echo HELLO > myfile.txt" into separate arguments as well. 5) I'd heard that pipes do not work in the same way when used via Java.
@abierto the directory that you want to be the current dir of the bash process, which is what the relative path in your redirection will be resolved against. And IOUtils is part of Apache commons-io, I use it as a convenient way to copy an input stream to an output stream but you can do it by hand if you prefer.
@AndrewThompson in this case no, you do want the whole echo-and-redirect as one argument because it's intended to be interpreted by bash, not by Java. Without bash in there you can't do redirects using > but in Java 7 at least you can send output directly to a file using the new methods added to ProcessBuilder in 7.
@IanRoberts What if I'm using Tomcat then? Is it a problem?
|
3
String echo = "echo 'hello' > myfile.txt";
ProcessBuilder pb = new ProcessBuilder("/usr/bin/bash", "-c", echo);
pb.start();

Comments

0

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

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

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 ServletContext for a path with getRealPath()

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.