find command argument -iname doesn't work from script when it's being used in a variable
iname="-iname '*py'"
echo iname: $iname
doesn't work:
find . $iname -exec grep "text" {} \;
works:
find . -iname '*py' -exec grep "text" {} \;
EDIT
Solution:
I followed @chepner's explanation, and did this in my real-world script (it's more readable than using arrays from my perspective)
inamecmd=-iname
inamearg=*py
find . $inamecmd $inamearg -exec grep "text" {} \;
etc.
When you type it out in full:
find . -iname '*py' -exec grep "text" {} \;
bash
uses the single quotes to recognize that you want to pass the literal string *.py
as an argument to find
. It then removes the single quotes; find
does not see them.
When you use a variable:
iname="-iname '*py'"
find . $iname -exec grep "text" {} \;
bash
expands $iname
to the literal string -iname '*py'
, but does not remove the single quotes. find
receives the literal string '*py'
as an argument, so only matches files starting with a single quote and ending with py'
.
Quoting the expansion of iname
wouldn't help:
find . "$iname" -exec grep "text" {} \;
This time, find
would receive as a single argument the string -iname '*py'
, rather than two separate arguments -iname
and '*py'
. bash
only performs one round of quote removal; it does not do so again on the result of the parameter expansion.
The correct way to pass multiple arguments to a command in a single variable is to use an array:
iname=(-iname "*py")
find . "${iname[@]}" -exec grep "text" '{}' \;
You can just use bash -c
:
bash -c "find . $iname -exec grep "text" {} \;"
OR better use BASH arrays :
iname=("-iname" "*sh")
find . "${iname[@]}" -exec grep "text" {} \;
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.