Tuesday, March 8, 2011

Unix: Using Standard Input & Output With Tar: Copying File & Directory Trees


Aside from its use to archive files/directories into archive media like tapes, magneto-optical disks etc., tar is also used to bundle-up multiple files and directories with their contents into a single tarfile.. The tarfile is also referred to as a tar-bundle or more popularly, a tarball. The way we usually run tar to create a tarball is simply like so:

tar -cvf tar_filename/tarball_name list_of_files_&_directories

Note:
* The -v option is ....well, optional  :-) It's just to make tar give you updates on what it is doing as it progresses.
* It is customary to suffix the tarball name with ".tar"

Instead of specifying a file name as a target to create a tarball as in the above command, you could specify a dash, "-",  in place of the tarball name to output directly to standard output, rather than to a file. With the archiving instruction/switch, -c, tar interprets "-"  as standard output.You can try this command on the shell to see what I mean:

tar -cvf - /etc/passwd /etc/hosts /tmp

Running the above command, you get a fast scrolling output on the screen (default destination of standard output) of the files /etc/passwd, /etc/hosts along with the directory /tmp and all of its contents and their contents recursively. A tarball 'stream' is being created and directed to standard output, at the same time. Assuming you have not redirected the standard-output, the net end-effect of the above command on what you see on the screen, is similar to what this command will produce:

tar -tvf  /tmp/temptarfile /etc/passwd /etc/hosts /tmp  && cat /tmp/temptarfile && rm /tmp/temptarfile

It is unchangeable reality - what gets tarballed, gets un-tarred. :-) To un-tar a tarball file, we usually do this: 

tar -xvf tarball

When we used '-' with the -c switch in tar it is regarded as standard output. Conversely, if you specify '-' with the -x switch to un-tar a tarball, the '-' is taken to be as standard input. Knowing this, the above command's result can also be obtained with the following:

cat tarball | tar -xvf  -

The first process which runs cat, reads out the tarball file to standard output. By virtue of the pipe "|", that process' standard output is chained to the standard input of the second process in which runs the "tar -xvf" command. Because of the "-", tar here reads its input from standard input, which is the cat command's output. And that output is a tarball stream.

We have seen the archive and un-tar operations separately. Combining them, and with the "-", we could use the tar utility to copy files/directories from disparate locations to another location within a host. Working with the original example, we could do the following:

tar -cvf - /etc/passwd /etc/hosts /tmp | tar -xvf - 

The above command, copies the files /etc/passwd & /etc/hosts and the directory tree /tmp into the current directory. Execute the command while being in your home directory.

Note:
* You can get an almost similar result to the above, with the 'cp' command used like so:

   cp -r /etc/passwd /etc/hosts /tmp .

There is a difference between copying with the tar and and with the cp command. Run them both and compare the results.

All the preceding examples, un-tars in the current directory. Should you wish to un-tar in another directory, you could do either:

tar -cvf - /etc/passwd /etc/hosts /tmp | tar -C my_directory -xvf -

or this:

tar -cvf - /etc/passwd /etc/hosts /tmp | { cd my_directory; tar -xvf -; }

Note:
* In relation to the above command, if your current working directory is not 'my_directory' and you wish it to remain so, you contain the 'cd' and 'tar -xvf' commands within curly braces { }. This ensures the 'cd my_directory' and 'tar -xvf  -'  commands get executed in a sub-shell. As a result, when the command is completed, your current working directory remains unchanged in the shell from where you invoked the commands.

No comments:

Post a Comment