![find: 'count=1': 해당 파일이나 디렉터리가 없습니다.](https://rvso.com/image/169395/find%3A%20'count%3D1'%3A%20%ED%95%B4%EB%8B%B9%20%ED%8C%8C%EC%9D%BC%EC%9D%B4%EB%82%98%20%EB%94%94%EB%A0%89%ED%84%B0%EB%A6%AC%EA%B0%80%20%EC%97%86%EC%8A%B5%EB%8B%88%EB%8B%A4..png)
이전 코드:
total=`ls -Rp rootfs | wc -l`
count=0
변수에 간단한 추가를 할당하는 경우:
sudo find rootfs -exec cp -d -- "{}" "/media/$USER/{}" 2> /dev/null \; -exec sync \; -exec count=$((count+1)) \; -exec echo -en "\rcopiati: $count/$total" \;
나는 얻다:
find: ‘count=1’: No such file or directory
또한 내가 실행할 때:
sudo find rootfs -exec cp -d -- "{}" "/media/$USER/{}" 2> /dev/null \; -exec sync \; -exec count=1 \; -exec echo -en "\rcopiati: $count/$total" \;
같은 오류가 발생합니다. 왜?
복사된 각 파일에 대해 카운터가 필요합니다: 1/13444, 이는 2/13444, 3/13444 등으로 업데이트됩니다.
편집하다:
메서드를 찾았지만 숨겨진 파일이 표시되지 않습니다. for 루프에서 숨겨진 파일을 볼 수 있도록 하려면 어떻게 해야 합니까?
#!/bin/bash
copysync() {
countfiles() {
for f in $1/*; do
if [ -d "$f" ]; then
countfiles "$f"
else
if [ "${f: -2}" != "/*" ]; then
total=$((total+1))
fi
fi
done
}
recursivecp() {
for f in $1/*; do
if [ -d "$f" ]; then
mkdir -p "/media/$USER/$f"
recursivecp "$f"
else
if [ "${f: -2}" != "/*" ]; then
sudo cp -a "$f" "/media/$USER/$f"
sudo sync
count=$((count+1))
echo -en "\rCopied: $((count*100/total))%"
fi
fi
done
}
total=0
countfiles $1
count=0
recursivecp $1
}
copysync rootfs
답변1
쉘은 count=$((count+1))
실행되기 전에 확장됩니다 find
.
그런 다음 인수를 명령으로 find
실행하려고 합니다 . -exec
이는 프로그램이나 스크립트여야 하며, 쉘 내장 또는 변수 할당을 위한 쉘 구문일 수 없습니다.
발견된 파일 수를 계산하는 것은 find
에 대한 새 프로세스를 시작하기 때문에 이 방식으로 작동하지 않습니다 -exec
. 따라서 변수 할당 결과는 상위 셸에서 사용할 수 없습니다.
발견된 모든 파일에 대해 한 줄을 인쇄하고 출력을 파이프로 연결하는 것이 좋습니다 find
. wc -l
예를 들어
find rootfs -exec cp -d -- "{}" "/media/$USER/{}" \; -exec sync \; -print|wc -l
파일을 복사하는 동안 일부 출력을 얻으려면 다음과 같이 사용할 수 있습니다.
find rootfs|while IFS= read -r file
do
cp -d -- "$file" "/media/$USER/$file"
sync
count=$((count+1))
echo -en "\rcopiati: $count/$total"
done
비고:
개행 문자(및 기타 특수 문자)가 포함된 파일 이름에는 작동하지 않습니다.
하위 디렉터리가 포함되어 있으면 스크립트가 작동하지 않을 수 있습니다 rootfs
. 이 문제를 방지 하려면 이 사례를 처리하거나 find
의 옵션을 사용해야 합니다 .-maxdepth
-type f
답변2
로 모든 명령을 실행하려는 것처럼 보입니다 -exec
. -exec
외부 명령만 실행 하므로 일반적인 경우에는 작동하지 않습니다 .
대신 단일 인라인 스크립트를 호출하고 find
해당 스크립트의 루프에 대한 생성기 역할을 하도록 하십시오.
find rootfs -type f -exec sh -c '
for pathname do
cp -d "$pathname" "/media/$USER" &&
echo . &&
sync
done' sh {} + | wc -l
그러면 디렉토리 안이나 아래에 있는 모든 일반 파일을 찾습니다 rootfs
. 이러한 파일 배치의 경우 짧은 인라인 sh -c
스크립트가 호출됩니다. 이 스크립트는 각 파일을 지정된 디렉토리에 복사하고, 성공적으로 복사된 각 파일에 대해 점과 개행 문자를 출력하고 sync
.
wc -l
출력된 도트 수를 계산하고 이 수를 보고합니다 . 경로 이름 자체에는 개행 문자가 포함된 경우 경로 이름 자체는 계산되지 않습니다. 이 계산은 오해의 소지가 있기 때문입니다.
를 사용하지 않고 find
다음과 같이 수행할 수 있습니다 bash
.
shopt -s globstar dotglob nullglob
for pathname in rootfs/**/*; do
[[ ! -f $pathname ]] && continue
cp -d "$pathname" "/media/$USER" &&
echo . &&
sync
done | wc -l
이는 쉘 옵션이 설정된 **
경우 하위 디렉토리 내부와 일치하는 glob을 포함하는 globbing 패턴을 사용합니다 . 또한 숨겨진 이름을 볼 수 있도록 globstar
설정했으며 , 패턴이 일치하지 않는 경우 루프 실행을 전혀 방지하는 셸 옵션도 설정했습니다.dotglob
nullglob
똑같지만 카운터가 있습니다.
shopt -s globstar dotglob nullglob
count=0
for pathname in rootfs/**/*; do
[[ ! -f $pathname ]] && continue
cp -d "$pathname" "/media/$USER" &&
count=$(( count + 1 ))
sync
done
printf 'count=%d\n' "$count"