On Thu, Oct 23, 2003 at 08:25:20AM -0600, Steve D wrote:
> On Wed, Oct 22, 2003 at 10:43:50PM -0600, Scott Gerhardt wrote:
> > I am having trouble combining the tar and find command.  I want to
> > tar and
> > delete all .bak,.Bak,.BAK files.
> >
> > I am using the following command but keep receiving errors.
> [...]
> > The script is as follows
> > =========================================
> > #! /bin/bash
> > set +x
> > TAR_DIR=/home/tarbackups;
> > FILES_DIR=/home/common;
> > tar --remove-files -cvzpf $TAR_DIR/bak_files_`date +%F`.tar.gz\
> >   `find $FILES_DIR -xdev -type f -iname "*.bak"`;
> > ==========================================
> [...]
> > Here is some error output returned:
> >
> > tar: jobs/ROOF: Cannot stat: No such file or directory
> > tar: LAYOUTS/RESIDENTIAL/FRASER/219: Cannot stat: No such file or
> > directory
> > tar: LEWIS: Cannot stat: No such file or directory
> > tar: CRES.bak: Cannot stat: No such file or directory
> [...]
> 
> --- --- ---
> 
> Matthew Seaman <[EMAIL PROTECTED]> replied:
> > The problem is that you have file/directory names like 'ROOF LAYOUTS'
> > which contain spaces and possibly other filenames containing
> > characters with syntactic significance to the shell.
> >
> > Try:
> >
> >     find $FILES_DIR -xdev -type f -iname "*.bak -print0 | \
> >         xargs -0 tar --remove-files -cvzpf $TAR_DIR/bak_files_`date
> > +%F`.tar.gz
> >
> 
> --- --- ---
> 
> Would the following approach also work? (Have sed surround each item
> returned by the find command with single quotes?)
> ---
> #! /bin/bash
> set +x
> TAR_DIR=/home/tarbackups;
> FILES_DIR=/home/common;
> tar --remove-files -cvzpf $TAR_DIR/bak_files_`date +%F`.tar.gz\
>     `find $FILES_DIR -xdev -type f -iname "*.bak" | sed "s/\(^.*$\)/'\1'/"`;
> ---
> 
> or the backticks in the last line replaced with the newer alternative "$()":
> 
>     "$( find $FILES_DIR -xdev -type f -iname "*.bak" | sed "s/\(^.*$\)/'\1'/" )" ;
> 
>  
> Do the characters \ * $ in sed's argument need to be quoted further,
> to protect them from interpretation by the shell? The "find" portion
> of the command works correctly, as written above, on my FreeBSD machine
> using /bin/sh or /usr/local/bin/bash, but I don't know why those 
> characters in sed's argument don't need to be further escaped.

You've apparently got double quotes inside a double quoted string.
That doesn't work.

Trying to enclose the output of find in quote marks will sort of work,
but it's generally found to be flaky.  Especially when the filenames
you're dealing with also contain quotation marks of various types or
return characters.  This is exactly why the '-print0' primitive for
find(1) was invented: it puts out a list of file names separated by
ascii NULL characters, which is one of the two ascii characters you
can't get in a filename. (The other is '/' -- the directory
separator).

The other great advantage of xargs(1) is that it knows how many
command line arguments it can supply to it's dependent command, and it
will chop up a long argument list into managable chunks.
Unfortunately the particular tar(1) command you're using can't be
restarted in that way so it doesn't help here. You'ld only run into
this problem if you were trying to backup many thousands of files, in
which case your quoting the output of find trick would suffer in
exactly the same way.

There are many ways to solve that problem, should you encounter it.
But I'll leave you to discover those for yourself if you need to.

        Cheers,

        Matthew

-- 
Dr Matthew J Seaman MA, D.Phil.                       26 The Paddocks
                                                      Savill Way
PGP: http://www.infracaninophile.co.uk/pgpkey         Marlow
Tel: +44 1628 476614                                  Bucks., SL7 1TH UK

Attachment: pgp00000.pgp
Description: PGP signature

Reply via email to