首先,不要这样做。最好的办法是正确使用find -exec:
# this is safe
find test -type d -exec echo '{}' +
另一个安全的方法是使用NUL终止列表,虽然这需要你找到支持-print0:
# this is safe
while IFS= read -r -d '' n; do
printf '%q\n' "$n"
done <
您还可以从find中填充数组,并稍后传递该数组:
# this is safe
declare -a myarray
while IFS= read -r -d '' n; do
myarray+=( "$n" )
done <
printf '%q\n' "${myarray[@]}" # printf is an example; use it however you want
如果你的find不支持-print0,你的结果是不安全的 – 如果文件存在包含换行符的名称(这是,是合法的),下面的行为将不会如所期望的:
# this is unsafe
while IFS= read -r n; do
printf '%q\n' "$n"
done <
如果一个人不打算使用上述之一,第三种方法(在时间和内存使用方面效率较低,因为它在字分割之前读取子过程的整个输出)是使用IFS变量不包含空格字符。关闭globbing(设置-f)以防止包含glob字符的字符串,如[],*或?从扩展:
# this is unsafe (but less unsafe than it would be without the following precautions)
(
IFS=$'\n' # split only on newlines
set -f # disable globbing
for n in $(find test -mindepth 1 -type d); do
printf '%q\n' "$n"
done
)
最后,对于命令行参数的情况,你应该使用数组,如果你的shell支持它们(即它的ksh,bash或zsh):
# this is safe
for d in "$@"; do
printf '%s\n' "$d"
done
将保持分离。注意,引用(和使用$ @而不是$ *)很重要。数组也可以通过其他方式填充,如glob表达式:
# this is safe
entries=( test/* )
for d in "${entries[@]}"; do
printf '%s\n' "$d"
done