I'm trying to parse the android source directory and i need to extract all the directory names excluding certain patterns. If you notice below., for now i included only 1 directory to the exclude list, but i will be adding more.,
The find command doesn't exclude the directory with name 'docs'.
The commented out line works., but the other one doesn't. For easy debugging, i included the min and maxdepth which i would remove later.
Any comments or hints on why it doesn't work?
#! /bin/bash
ANDROID_PATH=$1
root=/
EXCLUDES=( doc )
cd ${root}
for dir in "${EXCLUDES[@]}"; do
exclude_name_cmd_string=${exclude_name_cmd_string}$(echo \
"-not -name \"${dir}*\" -prune")
done
echo -e ${exclude_name_cmd_string}
custom_find_cmd=$(find ${ANDROID_PATH} -mindepth 1 -maxdepth 1 \
${exclude_name_cmd_string} -type d)
#custom_find_cmd=$(find ${ANDROID_PATH} -mindepth 1 -maxdepth 1 \
# -not -name "doc*" -prune -type d)
echo ${custom_find_cmd}
Building up a command string with possibly-quoted arguments is a bad idea. You get into nested quoting levels and
eval
and a bunch of other dangerous/confusing syntactic stuff.Use an array to build the
find
; you've already got the EXCLUDES in one.Also, the repeated
-not
and-prune
seems weird to me. I would write your command as something like this:The upshot is, you want the argument to
-name
to be passed tofind
as a literal wildcard thatfind
will expand, not a list of files returned by the shell's expansion, nor a string containing literal quotation marks. This is very hard to do if you try to build the command as a string, but trivial if you use an array.Friends don't let friends build shell commands as strings.
Found the problem. Its with the escape sequence in the exclude_name_cmd_string. Correct syntax should have been
When I run your script (named
fin.sh
) as:one of the lines of trace output is:
Do you see the single quotes around the double quotes? That's
bash
trying to be helpful. I'm guessing that your "doesn't work" problem is that you still get directories underdoc*
included in the output; other than that, it seems to work for me.How to fix that?
...it seems you've found a way to fix that...I'm not sure I'd trust it with a Bourne shell (but the Korn shell seems to agree with Bash), but it looks like it might work with Bash. I'm pretty sure this is something that changed during the last 30 years or so, but it is hard to prove that; getting hands on the old code is not easy.
I also wonder whether you need repeated
-prune
options if you have repeated excluded directories; I'm not sufficiently familiar with-prune
to be sure.