我想在变量中编写一串命令行参数,然后使用它们来执行命令。我在下面展示了一个简化的示例。这是一个名为“listfiles”的脚本。它读取一个名为“忽略”的文件而不列出文件,然后应该列出除这些文件之外的所有文件。完成我想做的事情的最佳方法是什么?
ignorelist=( `cat "./ignore" `)
for LINE in "${ignorelist[@]}"
do
Ignore="$Ignore -path '$LINE' -prune -o ";
done
find ${Ignore} -print
忽略文件的内容(两个目录名),:
./d1
./d2
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
我希望 d1 和 d2 以及下面的所有内容不包含在输出中,或者忽略文件中的任何文件/目录不包含在输出中。将整个命令存储在 var 中并对其进行评估会更好吗?
答案1
始终使用数组来存储以下内容分离。确保为 构建一组有效的选项find
。不要在参数中嵌入额外的引号(这最终会导致命令失败)。
#!/bin/bash
readarray -t ignorepaths <./ignore
ignoreopts=()
for pathname in "${ignorepaths[@]}"; do
ignoreopts+=( -o -path "$pathname" )
done
find . \( "${ignoreopts[@]:1}" \) -prune -o -print
也可以看看
- 使用 shell 变量作为命令选项 ...和别的。
为了/bin/sh
:
#!/bin/sh
set --
while IFS= read -r pathname; do
set -- "$@" -o -path "$pathname"
done <./ignore
shift
find . \( "$@" \) -prune -o -print