우분투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
을 사용하는 것입니다 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)
회로망주택 검사위의 두 클립 중 어느 것에도 문제가 보고되지 않았습니다.