[plug] Simple bash scripting problem (again)

Craig Ringer craig at postnewspapers.com.au
Mon Oct 10 20:56:30 WST 2005


Richard Meyer wrote:

>On Mon, 2005-10-10 at 19:28 +0800, Timothy White wrote:
>
>I've found out that the following find command does it
>
>richard1 at Selous:~/project> cat test.sh
>#!/bin/bash
>        find . -name "$@" -print
>  
>
That'll work, but probably not how you expect. Consider:

$ ./test.sh "a b c"

That'll find a file named "a b c" in any subdirectory, and print the 
path to it. However, you'll get a pretty odd result if you call it as:

$ ./test.sh "a b c" d

... since your `find' command expands to:

find . -name "a b c" d -print

If you want the effect of:

find . -name "a b c" -print -o -name d -print

then you need to go about it another way. The script you posted makes no 
sense with more than one argument unless you want to do something awful 
like call it as:

$ ./test.sh "a b c" -print -o -name

so it should only accept one argument, eg:

if (( $# != 1 )); then
   echo "Usage: `basename $0` nametofind"
   exit 1
fi
find . -name "$1" -print

or it should properly handle multiple names.

>If I may make a suggestion, try reading find with the "-exec" option and
>see whether you can get it to do what you want
>  
>
For efficiency it can often be better to use:

find .... -print0 | xargs -0 command

where `command' takes a list of one or more files to operate on, as 
generally output by find. The -print0 and -0 use NULLs to separate the 
filenames instead of newlines, which helps if you have some very strange 
filenames to deal with.

In this case, though, a shell script looks like the ideal way to tackle 
what he seems to be doing - it's just a matter of navigating a few 
pitfalls first.

--
Craig Ringer



More information about the plug mailing list