Java:重定向的Shell命令

时间:2016-02-07 01:26:33

标签: java shell ubuntu io-redirection

我正在尝试使用java在shell中执行重定向,但我得到一个空file1.txt命令:ls -all > file1.txt

尽管ls -all已正确执行。

commandLine的类型为String,并且具有我想要执行的命令。
例如String commandLine = "ls -all";

代码段(这是代码的相关部分):

   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();
    }

最后,我正在处理实例output的输出 另外,我想执行类似于curl -v http://www.centos.org > /dev/null的命令,但这也给了我一个空的响应!

1 个答案:

答案 0 :(得分:2)

简短回答

您正在阅读stdout,因为您将stdout重定向到/dev/null,所以该文件为空。使用getErrorStream()代替getInputStream()获取stderr

stdoutstderr

每个流程都有2个输出流,stdoutstderr。在上述curl -v http://www.centos.org的情况下,2个输出流将是以下流:

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

>运算符仅重定向stdout,但stderr将不受影响。

终端中的执行

在终端中,您通常会看到stdoutstderr混合。因此,如果您执行curl -v http://www.centos.org > /dev/null,则stdout将被重定向到/dev/null,但您仍会看到stderr的输出。这就是你观察到的,当你说&#34; 在bash上运行相同的命令时会给出一个输出。&#34;

从Java执行

另一方面,从Java执行命令将使两个流分开。可以使用stdout获取流process.getInputStream(),并使用stderr获取process.getErrorStream()

您使用的是前者(stdout),但由于stdout在您的示例(/dev/null)中被重定向到curl -v http://www.centos.org,因此它并非如此一个惊喜,你没有看到任何输出。

您可以获得的唯一输出是stderr。为此,您必须将process.getInputStream()替换为process.getErrorStream()

清空file1.txt

您在注释中声明文件file1.txt在从Java执行此ls -all > file1.txt之类的命令后为空。

最可能的原因是ls的执行实际上失败了,但您没有看到错误消息,因为它打印到stderr - 您从未阅读过。{1}}。您声明相同的命令在终端中正常工作,但执行环境不同(不同的环境变量,不同的工作目录等),这可能使相同的命令失败。因此请阅读stderr以获取错误消息。

file1.txt的另一个可能原因是您检查了另一个文件,因为您不知道工作目录。我不止一次发生过检查错误文件的事情!检查时间戳以确保它是正确的文件。