I'm trying to use find -name in a sh script with a previously computed complex argument for the condition. Simplified, it goes likecond=-name '*.txt*find . $cond -lsBut now I have the problem that either the wildcard in $cond is expanded by the shell before calling find or not expanded by find.To test that, in an empty test directory I did:touch a.txt b.txt c.datand then iteratedcond=-name '*.txt'; echo $cond; find . $condwith different values for $cond, using all types of quoting/escaping I could think of.Either I get all four entries (including the . directory) or no files  or find complains about b.txt being an unknown primary or operator. Of course, the correct output should be just the two text files.Any hints? I'm sure I'm just missing something basic.
Shell script, find -name, and wildcard expansion
shell;find;quoting
In Bourne-like shells (except zsh), leaving a variable expansion unquoted in list context is the split+glob operator. In:cond=-name '*.txt'; echo $condThe content of $cond is first split according to the value of the $IFS special variable. By default, that's on ASCII space, tab and newline characters.So that's split into -name and '*.txt'. Then the glob part is applied. For each of those words that contain wildcard characters (here * in the second one), the word is expanded to the list of files that match that pattern or left untouched if no file is matched. So, '*.txt' would expand to the list of files in the current directory whose name starts with ' and end in .txt' or to '*.txt' if no file matches.That list of words is then passed as separate arguments to echo. If no file matched, that means echo will receive 3 arguments: echo, -name and '*.txt'.Of course, the same applies for the find command.You want the find command to receive the arguments -name and *.txt, so you need to tune your split+glob operator.You need the value of $IFS to match the separator you use in $cond. So for instance:cond='-name:*.txt'IFS=':'And you don't want the glob part of the split+glob operator, so you need to disable it with:set -fSo it becomes:cond='-name:*.txt'IFS=:; set -ffind . $cond -lsOr you could do:cond='-name *.txt'set -ffind . $cond -lsand assume $IFS has not been modified from its default value.Alternatively, if your shell supports arrays, you may want to use that instead of relying on a scalar variables and expecting the shell to split it upon expansion.This would work with ksh93, mksh, bash or zsh:cond=(-name '*.txt') # an array with two elements: -name and *.txtfind . ${cond[@]} -ls # elements of the array expanded as separate arguments                        # to find.