Copy files and directories recursively with tar

Contributor Icon Contributed by qmchenry Date Icon September 28, 2003  
Tag Icon Tagged: UNIX

Copying a directory tree and its contents to another filesystem using tar will preserve ownership, permissions, and timestamps. A neat trick allows using tar to perform a recursive copy without creating an intermediate tar file.


To copy all of the files and subdirectories in the current working directory to the directory /target, use:

tar cf - * | ( cd /target; tar xfp -)

The first part of the command before the pipe instruct tar to create an archive of everything in the current directory and write it to standard output (the – in place of a filename frequently indicates stdout). The commands within parentheses cause the shell to change directory to the target directory and untar data from standard input. Since the cd and tar commands are contained within parentheses, their actions are performed together.

The -p option in the tar extraction command directs tar to preserve permission and ownership information, if possible given the user executing the command. If you are running the command as superuser, this option is turned on by default and can be omitted.

Previous recipe | Next recipe |
 
  • bgebbie
    Note that the * will not copy any of the files prefixed with a . in the root directory. It is a little tricky to wild card these files because one does not want to include the . and .. directories so usually one adds .??* to pick up everything else except for 1 and 2 character filenames prefixed with the . e.g. .a, .bc. To copy these as well, you will want to list them by doing an ls -a
    in the root directory first and typing those explicitly.

    In Summary, I would recommend this instead:

    tar cf - * .??* | ( cd /target; tar xfp -)


    but first do:

    ls -a


    and if you see anything starting with a . (besides ..) that is not followed by more then two characters, add those as well e.g.

    tar cf - * .??* .a .z .bc | ( cd /target; tar xfp -)
  • Anonymous
    I take it cp -pR directory newplace doesn't do the job?
  • Anonymous
    Not always, no.

    for instance I recently used this to do a full path copy of some contents on a bad cdrom. For whatever reason I needed the entire path. So I did a variation and put it into a script so I could use it later. It went like this:

    #!/bin/bash

    find $1 | while read i;
    do tar cfv - $i | ( cd $2 ; tar xfpv - )
    done

    So I could do something like this on the command line:

    fullpathcp /dvd/Examples ~/tmp/copy

    probably not the best use of cpu resources, but I got plenty of cycles to spare.

    Also you can do interesting things with variations of this.

    Like if your on a ftp server and they have a ls.gz file. This lists the contents of the server so you can go like this:

    ftp server blah
    username:anonymous
    anonymous login ok. Please give E-mail address
    password:
    > get ls.gz "|gunzip - |less"
    or
    > get ls.gz "|gunzip - |grep p0rn"

    And that way you can scroll around up and down. Or untar a file and download it onto your system...
    > get big.fat.tar.gz "| (cd ~/tmp/ ; tar zxf -)"

    or at least something similar.

    Also you can use Netcat to transfer files similar to that and so on and so forth. It's but one peice in a puzzle you need to build bigger and better scripts.
  • Anonymous
    <ul id="quote"><h6>Anonymous wrote:</h6>Not always, no.

    for instance I recently used this to do a full path copy of some contents on a bad cdrom. For whatever reason I needed the entire path. So I did a variation and put it into a script so I could use it later. It went like this:

    #!/bin/bash

    find $1 | while read i;
    do tar cfv - $i | ( cd $2 ; tar xfpv - )
    done

    So I could do something like this on the command line:

    fullpathcp /dvd/Examples ~/tmp/copy

    probably not the best use of cpu resources, but I got plenty of cycles to spare.

    Also you can do interesting things with variations of this.

    Like if your on a ftp server and they have a ls.gz file. This lists the contents of the server so you can go like this:

    ftp server blah
    username:anonymous
    anonymous login ok. Please give E-mail address
    password:
    > get ls.gz "|gunzip - |less"
    or
    > get ls.gz "|gunzip - |grep p0rn"

    And that way you can scroll around up and down. Or untar a file and download it onto your system...
    > get big.fat.tar.gz "| (cd ~/tmp/ ; tar zxf -)"

    or at least something similar.

    Also you can use Netcat to transfer files similar to that and so on and so forth. It's but one peice in a puzzle you need to build bigger and better scripts.</ul>
  • x
    Better is
    tar cf - . | tar -C /target -xpf -
  • Mikel Stous
    I've usually seen it with B for reassembling short reads into full records (reading 4.2BSD pipes). In other words, rightsize the blocks for the filesystem.

    tar cf - * | ( cd /target; tar xfBp -)
blog comments powered by Disqus