For an assignment, I'm supposed to write a bash script that can act as a very basic find, but without actually using the find command. For example, if I put in this input:

my_find ~/homedir/ -name 'test*' -name '*.o' -type f

I need it to search ~/homedir/ for anything matching the name test* with the wildcard character, then AND that and search within those results for anything matching a *.o name, and finally (although possibly redundant), search for only files. Finally, it will list all the results.

As of now, I've made a variable that stores the directory path (dirpath=$1). I then use shift to get rid of the first argument, and then do this (note that -type isn't implemented yet):

while (($#)); do
    if [[ $1 == "-name" ]]; then
        # process the name here?
        shift 2 # get rid of -name "name"

I'm kind of wondering how I can structure or even do this. I have a partially done function that will recurse through the directory path, but I'm not sure how / where I can process the argument passed in. Here is the recursive function to look through each directory.

recurse_path () {
    for i in "$@"; do
        # process and store matching file names in the array?
        if [[ -d "${i}" ]]; then
            cd "${i}"
            recurse_path *

So how can I search for my matching file names and store the results in an array while using this function? Also, is this the right way to do this, or is there a potentially easier way to update the results I get as each command is looked at? I'm brand new to bash scripting so I would appreciate any advice.

  • 1
    If there is some reason to explore new bicycle if your function act in same way and with same arguments syntax like find?
    – Costas
    Commented Feb 25, 2015 at 9:45
  • @Costas I have to complete it as an assignment :( Otherwise I would most definitely just use find
    – Alex
    Commented Feb 25, 2015 at 9:50
  • not sure what exactly you are lack of . what is your skill level ? are you familiar with common programming languages like pascal or c ? if so , all you need is a man 1 bash . Commented Feb 25, 2015 at 10:57
  • 1
    You need to declare i as a local variable, for obvious reasons. Also after the cd and recurse_path you need to go back to the previous directory. Store that previous directory in another local variable.
    – wurtel
    Commented Feb 25, 2015 at 11:08
  • 1
    With globstar and dotglob set: printf '%s\n' ~/homedir/**/test*.o (apart from the filetype test).
    – Kusalananda
    Commented May 18, 2020 at 11:17

2 Answers 2


let me try point something basic .


if we already can travel through directory trees , next thing is to search in the current visiting directory . this depends on what style of pattern syntax we want to support . regex is a whole different thing . maybe we are satisfied with the shell built-in pattern grammar . then this will do .

for i in * ; do for p in <patterns> ; do
        if [[ $i == $p ]]
done ; done


for parsing the commandline , bash has the getopts builtin , refer to the manual .


for arrays , refer to the manual .

  • 1
    getopts can be used to parse single letter options, not find predicates. Commented Feb 25, 2015 at 11:26

A dirty solution would look like:


for arg in $*; do
   if [ ${boolRememberNext} -eq 1 ]; then
      rememberString="${rememberString} ${arg}"
   if [ "${arg}" = "-name" ]; then

echo ${rememberString} | while read filemask; do
   unquotedFile=$(echo "$filemask" | tr -d "'")
   ls -R1 ~/homedir/ | grep ":" | cut -d: -f1 | while read dir; do
      ls ${dir}/unquotedFile

Why is it dirty?

  • A lot of loops, the filesystem is accessed many times
  • Incorrect commmandline syntax is ignored
  • directory and file names may not have an : inside
  • the unquoting of the var with tr will not handle * combinations
    I do not want to use eval for this

What could be done to improve the solution?

You can store intermediate results in local var's, improve handling of special chars and check the syntax.

You can also perform a ls ~/homedir/* and add an asterisk to the searchpath until no files are found. Parse all files through some filter (awk?). Check the files you find, that they are files, not directories.

You must log in to answer this question.

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