Tutorial :Problem while executing “tar -ztf” command in Java



Question:

I am trying to run "tar -ztf /users/home/test.tar.gz | head -1" in Java, which worked when I tried to run it in unix command line directly.
The result of this command will list one line of the file/folder inside of the test.tar.gz. for example: proj/test/test_dir
But I when I run it in java. it will give this error:

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.  

Any idea what's wrong with it? why is it related to "specify drive and density" option?

The code I have run:

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


Solution:1

On the command line, the shell is doing the piping for you. Only the arguments before the | are passed to gtar. Your code incorrectly passes the pipe and the rest of the text as arguments to gtar.

Luckily, the solution is simple. You can simply read the first line yourself.

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.  }  


Solution:2

To elaborate Matthew's point, the | operator is interpreted by the shell. To run your command without the shell, you would need to launch the programs separately and connect their pipes together (tricky in Java).

If you input is sanitized, you can invoke the shell and give it the command to run. Its the easier approach, though arguably less portable. In general, the SHELL environment variable contains the user's shell. Shells also have a defacto standardized -c option to pass them a command string in argv. If you invoke $SHELL -c [command string], you should get the behavior you want.


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »