Problem with bash script

Karl Vogel vogelke+unix at
Tue Jun 16 18:12:24 UTC 2009

>> On Tuesday, June 16, 2009 08:09:09 -0500 Carmel NY 
>> <carmel_ny at> wrote:  

C> I am attempting to write a simple Bash script that will find all the
C> '*.pem' files in a directory structure and move them to another
C> directory.

   Using find and pax will correctly handle filenames with spaces and
   other crap.  If you use the -depth option in find, you'll also preserve
   directory modtimes:

     root# cd /src/directory
     root# mkdir -p /dest/directory
     root# find . -depth -print | pax -rwd -pe /dest/directory

   Use "-rwdu" if /dest/directory already exists and you don't want to
   overwrite newer files there with older files from /src/directory.  If
   you want to store the output from pax as an archive file, use the "cpio"
   format for the most portability and the least number of limitations on
   things like pathname size.

   Another advantage of find vs backquotes is the ability to filter things
   out of the files being copied:

     root# find . -depth -print | fgrep -f /files/to/ignore |
           pax -x cpio -wd | gzip -1c > /tmp/src.pax.gz

     [ archive the pax file, copy it to another system, etc. ]

     root# cd /dest/directory
     root# gunzip -c < src.pax.gz | pax -r -pe

   If you have spaces in your filenames and you still want to do some
   filtering before running xargs, use tr to change newlines to nulls:

     root# find . -depth -print | /some/filter/here |
           tr '\012' '\000' | xargs -0 /some/command

>> On Tue, 16 Jun 2009 16:16:26 +0100, 
>> "Daniel Bye" <danielby at> said:

D> It does exactly the same as `command -a rgs`, but all characters between
D> the parentheses are taken literally (in the backtick form, certain chars
D> have special meaning, but not in the $() form.)

   Either solution will run the command first and then rescan the line
   in the calling script.  You can run into problems when the results
   of the backquoted command are too big; there's an upper limit to how
   many arguments you can put in a for loop or pass to a program.  Also,
   any spaces or weird characters in the output are likely to play hell
   with whatever else you're doing.

   You're much safer using a pipe.  Use backquotes or $() when you're pretty
   sure the output won't be too big.  To be safe, check the argument count
   when you run something:

     set X `date`  # should give 6 tokens plus X.
     case "$#" in
         1) echo "command didn't print anything" ;;
         7) echo "success: $*"; echo "year should be 7th arg: $7" ;;
         *) echo "something else is wrong" ;;
     exit 0

Karl Vogel                      I don't speak for the USAF or my company

There is nothing more satisfying than having
someone take a shot at you and miss.               --Murphy's Laws of Combat

More information about the freebsd-questions mailing list