0
$ find -name "Bik*"
./Biking
./Biking/Unsync/Biking.md.~6~
./Biking/Rendered/Biking.gen.html
./Biking/Biking.md

Now when I substitute expression with a variable as follows:

$ a='-name "Bik*"'

$ find $a

I get no output. Why is it so? And what should be modified?

3

(Unless you are using zsh as your interactive shell...) The issue is that the double quotes will be taken as part of the pattern. The command that you are actually running would be the equivalent of

find . -name '"Bik*"'

You get this because the shell would perform word-splitting on the unquoted $a, splitting the string tho the two words -name and "Bik*". The words then undergo filename generation ("globbing"), which means that "Bik*" would be expanded to all the filenames matching that particular pattern in the current directory (including the double quotes). It's unlikely that you have any such filenames, so the pattern remains unexpanded, and the quotes remain.

If you had used a='-name Bik*', it would have worked, but only if you have nothing matching Bik* in the current directory.

If, in bash, you had used shopt -s nullglob, both attempts would have resulted in an error from find as -name would not have been given a pattern (the shell would have removed the unmatched patterns).

(In the zsh shell, you would get an error from find as it does not know what option -name "Bie*", i.e. the whole string, is; this is because the zsh shell does not perform these split-and-glob operations on unquoted expansions by default.)

Instead, if you are using a shell that has arrays, use

a=( -name 'Bik*' )
find . "${a[@]}"

This would properly quote each individual word when used with find in the way shown here.

Or, you could have used

a='Bik*'
find . -name "$a"

Related:

Also the second half of my solution to set -f inside function

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.