Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java: Shell commands with redirection

I am trying to execute redirection in shell using java, but I am getting an empty file1.txt for the command: ls -all > file1.txt.

Although ls -all is executed properly.

commandLine is of type String and has the command that I would want to execute.
for example String commandLine = "ls -all";

Code Snippet(This is the relevant section of the code) :

   StringBuilder output = new StringBuilder();
   Runtime runtime = Runtime.getRuntime();
    Process process = runtime.exec(new String[]{"/bin/sh", "-c", commandLine});
    process.waitFor();

    try {
         BufferedReader reader = 
           new BufferedReader(new InputStreamReader(process.getInputStream()));

          String line;          
          line = "";
          while ((line = reader.readLine())!= null) {
              output.append(line);
              output.append("\n");
          }
    } 
    catch(Exception ex) {
      ex.printStackTrace();
    } 
    finally {
      process.destroy();
    }

Finally I am processing the output from the instance output.
Also, I want to execute the command similar to curl -v http://www.centos.org > /dev/null but this gives me an empty response too !

like image 997
Prameet Singh Kohli Avatar asked Aug 09 '26 17:08

Prameet Singh Kohli


1 Answers

Short answer

You are reading stdout, which is empty because you redirected stdout to /dev/null. Use getErrorStream() instead of getInputStream() to get stderr.

stdout and stderr

There are 2 output streams of every process, stdout and stderr. In the case of the mentioned curl -v http://www.centos.org, the 2 output streams would be the following streams:

stdout:

<html>
<head><title>301 Moved Permanently</title></head>
<body bgcolor="white">
<center><h1>301 Moved Permanently</h1></center>
<hr><center>nginx/1.6.3</center>
</body>
</html>

stderr:

* Rebuilt URL to: http://www.centos.org/
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0*   Trying 85.12.30.226...
* Connected to www.centos.org (85.12.30.226) port 80 (#0)
> GET / HTTP/1.1
> Host: www.centos.org
> User-Agent: curl/7.43.0
> Accept: */*
> 
< HTTP/1.1 301 Moved Permanently
< Server: nginx/1.6.3
< Date: Thu, 19 May 2016 15:31:03 GMT
< Content-Type: text/html
< Content-Length: 184
< Connection: keep-alive
< Location: https://www.centos.org/
< 
{ [184 bytes data]
100   184  100   184    0     0   1184      0 --:--:-- --:--:-- --:--:--  1187
* Connection #0 to host www.centos.org left intact

The > operator will redirect only stdout, but stderr will be untouched.

Execution in the terminal

In terminals you usually see stdout and stderr mixed. So if you execute curl -v http://www.centos.org > /dev/null, then stdout will be redirected to /dev/null, but you will still see the output of stderr. That's what you observe, when you say that "running the same command on bash gives [...] an output."

Execution from Java

Execution of a command from Java, on the other hand, will keep the two streams separated. The stream stdout can be obtained using process.getInputStream(), and stderr can be obtained using process.getErrorStream().

You are using the former (stdout), but since stdout is redirected to /dev/null in your example (curl -v http://www.centos.org), it doesn't come as a surprise that you don't see any output.

The only output you could obtain would be stderr. For that you would have to replace process.getInputStream() by process.getErrorStream().

Empty file1.txt

You are stating in the comments that the file file1.txt is empty after executing some command like this ls -all > file1.txt from Java.

The most likely reason for this is that the execution of ls actually failed, but you don't see the error message because it is printed to stderr - which you never read. You state that the same command works fine in the terminal, but execution environments are different (different environment variables, different working directory, etc.), which can make the same command fail. So read stderr to get the error message.

Another possible reason for an empty file1.txt is that you check a different file because the working directory is unknown to you. Happened to me more than once that I checked the wrong file! Check the timestamp to make sure that it's the correct file.

like image 132
mastov Avatar answered Aug 11 '26 07:08

mastov



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!