Problem with bash script
Karl Vogel
vogelke+unix at pobox.com
Tue Jun 16 18:12:24 UTC 2009
>> On Tuesday, June 16, 2009 08:09:09 -0500 Carmel NY
>> <carmel_ny at hotmail.com> 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 slightlystrange.org> 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:
#!/bin/bash
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" ;;
esac
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