乌班图16.04
#!/bin/bash
site="hello"
wDir="/home/websites/${site}/httpdocs/"
for file in $(find "${wDir}" -name "*.css")
do
echo "$file";
done
exit 0;
即使我定义了起始目录,shellcheck 也会警告我,但脚本工作得很好。
root@me /scripts/ # shellcheck test.sh
In test.sh line 6:
for file in $(find "${wDir}" -name "*.css")
^-- SC2044: For loops over find output are fragile. Use find -exec or a while read loop.
答案1
问题正是 shellcheck 告诉您的:迭代或类似命令for
的输出的循环是脆弱的。find
例如:
$ ls
'a file with spaces'
$ for file in $(find . ); do echo "$file"; done
.
./a
file
with
spaces
安全的方法是使用-exec
of find
:
$ find . -exec echo {} \;
.
./a file with spaces
或者使用while
循环:
$ find . -print0 | while IFS= read -r -d '' file; do echo "$file"; done
.
./a file with spaces
答案2
使用for
循环输出find
充其量是一种反模式。看BashFAQ/001 - 如何逐行(和/或逐字段)读取文件(数据流、变量)?因为原因。将while
如下所示的循环与命令一起使用read
。下面的命令find
使用 NULL 字节来分隔输出,并且read
命令通过分割该字节来读取,以便安全地处理名称中包含特殊字符的所有文件(包括换行符)
#!/usr/bin/env bash
site="hello"
wDir="/home/websites/${site}/httpdocs/"
find "${wDir}" -name "*.css" -type f -print0 | while IFS= read -r -d '' file; do
printf '%s\n' "$file"
done
或者完全避免使用管道并进行流程替代
while IFS= read -r -d '' file; do
printf '%s\n' "$file"
done< <(find "${wDir}" -name "*.css" -type f -print0)
网络外壳检查没有报告上述两个片段中的任何一个的任何问题。