1

我正在尝试在 Java 中运行“tar -ztf /users/home/test.tar.gz | head -1”,当我尝试直接在 unix 命令行中运行它时,它起作用了。
此命令的结果将列出 test.tar.gz 内的文件/文件夹的一行。例如: proj/test/test_dir
但是我在 java 中运行它时。它会给出这个错误:

Running command: tar -ztf /users/home/test.tar.gz | head -1
     [java] tar: Options `-[0-7][lmh]' not supported by *this* tar
     [java] Try `tar --help' for more information.

知道有什么问题吗?为什么它与“指定驱动器和密度”选项有关?

我运行的代码:

 String s = null;
 StringBuffer sbOutput = new StringBuffer();
  StringBuffer errorInfo = new StringBuffer();
  String[] cmd = {"tar", "-ztf", fileName, "|", "head", "-1"};
  try
     {
      Runtime rt = Runtime.getRuntime();
      System.out.println("Running command: " + cmd[0] + " " + cmd[1] + " " + cmd[2] + " " + cmd[3] + " " + cmd[4] + " " + cmd[5]);
        Process p = rt.exec(cmd);            

        BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
        BufferedReader stdError = new BufferedReader(new InputStreamReader(p.getErrorStream()));      

        //If there is an error - only show that
        while ((s = stdError.readLine()) != null)
        {
            errorInfo.append(s + "\n");
        }
        if (errorInfo.length() > 0)
        {
         System.out.println(errorInfo.toString());            
        }

        while ((s = stdInput.readLine()) != null) {
         sbOutput.append(s + "\n");
        }


  // wait for end of command execution
  try {
   p.waitFor();
  } catch (InterruptedException ie) {            
   new LogErrThread(ie).start();
   ie.printStackTrace();
     } 

        p.destroy();

        if (sbOutput.length() > 0)
        {
         System.out.println(sbOutput.toString()); 


        }

 }
    catch (IOException e)
    {            
     new LogErrThread(e).start();
  e.printStackTrace();
    }
4

2 回答 2

2

在命令行上,shell 正在为你做管道。只有在 之前的参数|被传递给 gtar。您的代码错误地将管道和文本的其余部分作为参数传递给 gtar。

幸运的是,解决方案很简单。您可以简单地自己阅读第一行。

String[] cmd = {"gtar", "-ztf", fileName};

// ...

// Instead of current input loop.
s = stdInput.readLine();
if(s != null) {
    sbOutput.append(s + "\n");
}

while (stdInput.readLine() != null) {
    // Disregard.  Reading to end to prevent hang.
}
于 2010-07-16T05:38:09.337 回答
2

为了详细说明 Matthew 的观点,|操作符由 shell 解释。要在没有 shell 的情况下运行命令,您需要单独启动程序并将它们的管道连接在一起(在 Java 中很棘手)。

如果您的输入被清理,您可以调用 shell 并给它运行命令。它是一种更简单的方法,尽管可以说不那么便携。一般来说,SHELL环境变量包含用户的shell。Shell 还有一个事实上的标准化-c选项,可以在 argv 中向它们传递命令字符串。如果你调用$SHELL -c [command string],你应该得到你想要的行为。

于 2010-07-16T05:42:51.947 回答