find: 'count=1': 해당 파일이나 디렉터리가 없습니다.

find: 'count=1': 해당 파일이나 디렉터리가 없습니다.

이전 코드:

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

쉘 옵션이 설정된 경우 **inte 하위 디렉토리와 일치하는 glob을 포함하는 globbing 패턴이 사용됩니다. 또한 패턴이 일치하지 않는 경우 실행 루프를 완전히 피하기 위해 숨겨진 이름과 쉘 옵션을 볼 수 있도록 globstar설정했습니다 .dotglobnullglob

같은 일이지만 카운터가 있는 경우:

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"

관련 정보