Thursday, 31 August 2017

Tar and untar files simultaneously in a single command


In this quick article I'll demonstrate how we can perform a tar and untar operation on a file or directory simultaneously. We'll be looking at two scenarios. The first will be archiving and extracting the file in a different folder on the same server and a second scenario to archive and extract files on a different server using ssh. Additionally we'll brief look at subshells in bash.

The one liner command for the first scenario is as follows:

tar -cvf - python-jinja2-28-2.8-1.el7.R.noarch.rpm | (cd /tmp/; tar xvf -)


This will perform a tar of the file python-jinja2-28-2.8-1.el7.R.noarch.rpm and the generated output of this command i.e. the tar archive will be piped to the input of the next tar command to extract the archive. The first dash (-) here tells tar to send it's output to stdout instead of a file. the second dash(-) with the tar command tells tar to read it's input from stdin being piped to it instead of a file. This is not a shell construct and does not work with all commands. I've known it to work with file, cat and diff command though.

The interesting part in the tar happens after the pipe. By using parenthesis i.e. () , we invoke the commands within the parenthesis in a sub shell. The subshell executes the commands enclosed within parenthesis simultaneously and exits and we get our old shell back. So after I run the command I don't end up in /tmp directory when the command finishes. I remain in my present working directory.

The parenthesis groups the commands and executes them as a single unit. We often use parenthesis for command grouping bu there's another method available for grouping commands like this would invoking a subshell and that is via curly braces {}. This involves placing the commands to be executed within curly braces and the last command must have a semicolon following it. Here's an example:

[root@pbox ~]# { cd /tmp; ls -l; pwd; }




Here' s a screenshot of what went down when I ran the tar command one liner:




Now this trick only appears to work if I use dashes to substitute the archive name.

In the second scenario we do the same thing but this time on a different server via ssh. Here's the command.

tar -cvf - python-jinja2-28-2.8-1.el7.R.noarch.rpm | ssh root@192.168.188.133 "(cd /tmp/; tar xvf -)"


This indeed archives the file on the source server and then extracts it on the destination server.

No comments:

Post a Comment

Using capture groups in grep in Linux

Introduction Let me start by saying that this article isn't about capture groups in grep per se. What we are going to do here with gr...