在Java中执行“tar -ztf”命令时出现问题

时间:2010-07-16 05:35:43

标签: java unix

我正在尝试在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();
    }

2 个答案:

答案 0 :(得分: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.
}

答案 1 :(得分:2)

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

如果您输入已清理,则可以调用shell并为其提供运行命令。它更简单的方法,虽然可移动性较差。通常,SHELL环境变量包含用户的shell。 Shell还有一个defacto标准化-c选项,可以在argv中传递命令字符串。如果你调用$SHELL -c [command string],你应该得到你想要的行为。