The script which I have requires two inputs one is the filepath and the other being filename which is used to check the existence of a file using find command.



if [ -z "$Filepath" ] && [ -z "$Filename" ]
        echo "Requires Input"
elif [ ! -z "$Filepath" ] && [ ! -z "$Filename" ]
        Found=`find "$Filepath" -iname "$Filename"`
                if [ -z "$Found" ]
                        echo "Not Found"
                        echo $Found

This works completely fine as expected. Later I had to add couple of more conditions to this script i.e. if we get only the filename as the input parameter the we have search that file in the entire file system as given below

find / -iname "$Filename"

And in case if only the filepath input parameter is passed to this script then it has to echo that file name parameter is also required or just has to come out.

  • What is the question you're attempting to ask?
    – John
    Commented Sep 28, 2016 at 15:01
  • Based on the input parameters I have to execute the condition. Basically I have two input parameters for my script and I need four condition to be made, 1. If both parameters are passed (filepath and filename) then it has to execute the find command with the both. 2.If both the parameters are not passed then prompt of echo asking for the input parameters. 3.If only filepath ($1) parameter is passed then it has to prompt asking for the filename. 4.If only filename ($2) parameter is passed to the script then it has to search the entire system i.e. "/" for that file.
    – ramp
    Commented Sep 28, 2016 at 15:17

1 Answer 1


I'd do:

#! /bin/sh -
pattern=${1?Please provide a file name}

[ "$#" -gt 0 ] || set /

find "$@" -iname "$pattern" | grep '^' && exit

echo >&2 "Not found"
exit 1

That is, pass the name (note that find treats it as a (case insensitive because of -iname) pattern to match agains file names, not as an exact file name to find) as the first argument. Any other argument are directories or files to search in, and if none is given, search in /.

Rather than storing the output in a variable and display it at the end, use grep as a pass-through and that reports true if a file has been found.

Also, I'm outputting the "Not found" message on stderr instead of stdout, and reporting the failure to find the file in the exit status.

As noted by @ThomasN, there's the usual problem that you can't pass file/directory names reliably to find. If you want to search in a directory called -delete, calling that-script name -delete for instance would have disastrous effects. With BSDs find, that can be worked around by doing (before calling find):

for i do
  set -- "$@" -f "$i"

Portably (though note that -iname is not portable), you'd need to prepend ./ to relative paths that may be problematic like with:

for i do
  case $i in
    (. | ./* | /*) ;; # /foo, ./foo are not a problem
    (*) i=./$i
  set -- "$@" "$i"
find "$@"...

That does affect the output though (as in you'll see ./delete/name instead of -delete/name).

  • 1
    While this passes the requirements test, some input validation on $@ would be helpful to prevent garbage (or malice) from destroying data. E.g., (assuming the script is named finder_script.sh): ./finder_script.sh some_file /home/mydir/ -ok rm \{\} \;
    – Thomas N
    Commented Sep 28, 2016 at 16:00
  • @ThomasN, yes, that's an usual problem with find in that you can't pass it arbitrary file names reliably. BSD find has the -f option for that but it's not supported by GNU find yet, so we'd need to prepend ./ to all relative paths which would affect the output. Commented Sep 28, 2016 at 16:21

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .