file patterns and tar

youshi10 at u.washington.edu youshi10 at u.washington.edu
Thu Aug 30 10:46:27 PDT 2007


On Thu, 30 Aug 2007, CyberLeo Kitsana wrote:

> Jim Stapleton wrote:
>> I want to create a backup of some parts of my system, but not everything
>>
>> ex, I want to exclude /bin, and /usr/bin, but not /usr/local/bin -
>> same for *sbin, *lib, and *libexec
>>
>> however, if I used
>>
>> tar -jcvf test.tbz  \
>>       --exclude /bin --exclude /usr/bin \
>>       --exclude /dev --exclude /var --exclude /tmp \
>>       --exclude /root --exclude /proc / | \
>> tar -tf - | grep bin
>>
>> I don't get /usr/local/bin files.
>>
>> I coudln't find more help in tar, either through tar --help or man
>> tar, though I know it says that it is excluding leading slashes in
>> file names (which is probably causing this issue). What should I do,
>> short of running tars for /, /usr/ and /usr/local, or is that the only
>> real option? But then there is always the possiblility of missing
>> something because its name just happens to contain bin, or more likely
>> contains lib.
>
> If you're going for really wacky patterns, and don't mind wrestling with
> find(1), you could always pipe the output of find into tar:
>
> find Pictures -type f -name '*.jpg' -print0 | tar cvTf - jpegs.tar --null
>
> --
> Fuzzy love,
> -CyberLeo
> Technical Administrator
> CyberLeo.Net Webhosting
> http://www.CyberLeo.Net
> <CyberLeo at CyberLeo.Net>
>
> Furry Peace! - http://wwww.fur.com/peace/

Try --exclude '^/bin'. Not sure if that will work (should work if tar(1) is regex capable), but it's worth a try...

You might want to preprocess the directories through sed or perl first, then skip the root directories.

Something like what I've written below should work (at least for skipping root directories blacklists, and skipping internal directories).

Cheers,
-Garrett

#!/usr/bin/env perl
#
# This script skips over blacklist directories,
# by traversing down each search directory, bsd-globbing
# for results, then printing out the directories
# one-by-one to be inserted into the bourne shell script
# shown below.

use Cwd 'abs_path';
use File::Glob qw(:glob :case);

# Literal paths to exclude
@blacklist_dirs = (
     '/bin',
     '/sbin'
     # etc, etc..
);

@search_dirs = (
     '/',         # root
     '/usr/local' # /usr/local
);

foreach $search_dir (@search_dirs) {

     chdir $search_dir || die "Cannot chdir to $dir";

     # Use glob to find all the directories in $search_dir's root.
     foreach(bsd_glob("./*")) {

         # Get the absolute path for the glob
         # (since we're chdir'ed to a different
         # directory currently).
         $check_dir = abs_path($_);

         # Replace trailing '/' added by abs_path with ''.
         $check_dir =~ /\/$//;

         # Regex protect path -- want to interpret it literally
         #
         # Grep will return true if an entry in @blacklist_dirs
         # matches the exact interpretation of $check_dir.
         #
         # We don't want to print the path if it matches.
         if(!grep(/^\Q$search_dir$check_dir\E/, @blacklist_dirs) {
             print "$check_dir\n";
         }

     }

}

==================

#!/bin/sh
#
# This script delegates the blacklisting off
# to the perl script shown above, then takes
# the results printed and tars them, and
# finally bzip's the whole lot down below.

FILENAME_SUFFIX="foo"

for i in `perl_script.pl`; do
     tar -cvTf $FILENAME_SUFFIX.tar
done

# This will make $FILENAME_SUFFIX.tar.bz2
bzip2 -z $FILENAME_SUFFIX.tar



More information about the freebsd-questions mailing list