0

I would like to compose a string of command line arguments in a variable, then use those to execute a command. I show a simplified example below. It's is a script called "listfiles." It reads a file called "ignore" of files not to list, then is supposed to list every file except those. What's the best way to accomplish what I'm trying to do?

ignorelist=( `cat "./ignore" `)
for LINE in "${ignorelist[@]}"
        do
                Ignore="$Ignore -path '$LINE' -prune -o ";
        done

find ${Ignore} -print

content of ignore file (two directory names), :

./d1
./d2

output of bash -x listfiles:

+ ignorelist=(`cat "./ignore" `)
++ cat ./ignore
+ for LINE in '"${ignorelist[@]}"'
+ Ignore=' -path '\''./d1'\'' -prune -o '
+ for LINE in '"${ignorelist[@]}"'
+ Ignore=' -path '\''./d1'\'' -prune -o  -path '\''./d2'\'' -prune -o '
+ find -path ''\''./d1'\''' -prune -o -path ''\''./d2'\''' -prune -o -print
.
./1
./2
./3
./d1
./d1/4
./d1/d1a
./d1/d1a/5
./d2
./ignore
./listfiles

I would like it so that d1 and d2 and everything under is not included in the output, or so whatever files/directories are in the ignore file are not included in the output. Would storing the whole command in a var and evaling it be better?

dougd_in_nc
  • 103
  • 4

1 Answers1

2

Always use arrays to store things that are separate. Make sure you build a valid set of options for find. Don't embed extra sets of quotes in the arguments (this is ultimately what makes your command fail).

#!/bin/bash

readarray -t ignorepaths <./ignore

ignoreopts=() for pathname in "${ignorepaths[@]}"; do ignoreopts+=( -o -path "$pathname" ) done

find . ( "${ignoreopts[@]:1}" ) -prune -o -print

See also


For /bin/sh:

#!/bin/sh

set -- while IFS= read -r pathname; do set -- "$@" -o -path "$pathname" done <./ignore

shift

find . ( "$@" ) -prune -o -print

Kusalananda
  • 333,661