2014-01-15 2 views
0

백업 스크립트를 작성 중이며 문제가 있습니다. 내 문서를 FTP 서버에 백업하고 싶습니다. 왜냐하면 나는 encfs를 좋아하지 않기 때문에 z-zip과 암호화 된 아카이브를 사용하여이를 실현하려고 노력합니다. 이것은 잘 작동하지만 하위 디렉토리 내의 파일이 변경되어 lftp가 변경된 파일 만 업로드 할 때만 새로운 아카이브를 만들고 싶습니다.디렉토리가 변경되었는지 확인하십시오.

내 codesnippet은 다음과 같습니다

cd /mnt/HD_a2/documents 
for i in */ 
do 7za a -t7z /mnt/HD_a2/encrypted/ul_doc/"${i%/}.7z" -p1234 -mhe "$i" 
done 

어떻게 내부의 파일이 "내가"지난 7 일 이내에 변경된 경우에만 새 아카이브를 생성 그래서이 코드를 변경할 수 있습니까?

답변

0

그래서, Barmar`s answer 거의 권리입니다 (이 스크립트는 7 일마다 크론에 의해 실행),하지만 파일을 올바르게 계산하지 않습니다. 나는 다른 비슷한 질문을 둘러 보았고 일반적인 실수 인 것처럼 보였다. (그의 해결책은 중요하지 않지만 대부분의 사람들이 그렇게하지 않기 때문에 다른 프로그래머와 접촉하는 것을 혼란스럽게 할 수있다. expect), 아무도 파일 이름에 개행 문자가 포함될 수 있다는 사실을 알지 못합니다. 여기에 적절한 파일 수를 제공하는 조금 더 나은 버전이 있습니다 :

for i in */ 
do 
    fileCount=$(find "$i" -type f -mtime -8 -exec printf . \;) 
    if ((${#fileCount} > 0)); then 
     7za a -t7z /mnt/HD_a2/encrypted/ul_doc/"${i%/}.7z" -p1234 -mhe "$i" 
    fi 
done 

하지만 수천 개의 파일이 있다면 어떻게 될까요? 그러면 파일 수만큼의 문자열이 작성됩니다.

그래서 우리는 이것을 사용할 수 있습니다

for i in */ 
do 
    fileCount=$(find "$i" -type f -mtime -8 -exec printf . \; | wc -c) 
    if ((fileCount > 0)); then 
     7za a -t7z /mnt/HD_a2/encrypted/ul_doc/"${i%/}.7z" -p1234 -mhe "$i" 
    fi 
done 

또는이 :

for i in */ 
do 
    fileCount=$(find "$i" -type f -mtime -8 -exec echo \; | wc -l) 
    if ((fileCount > 0)); then 
     7za a -t7z /mnt/HD_a2/encrypted/ul_doc/"${i%/}.7z" -p1234 -mhe "$i" 
    fi 
done 

을 쓸모없는 문자열 데이터를 캐시하지 않을 것으로 기대.

하지만 파일 하나가 있는지 알아야합니다. 모든 파일을 계산할 필요는 없습니다. 이렇게하면 뭔가 발견되면 즉시 중단 할 수 있습니다.

for i in */ 
do 
    fileFound=$(find "$i" -type f -mtime -8 | head -n 1) 
    if [[ $fileFound ]]; then 
     7za a -t7z /mnt/HD_a2/encrypted/ul_doc/"${i%/}.7z" -p1234 -mhe "$i" 
    fi 
done 

그게 전부입니다. 이 솔루션은 다른 파일을 찾을 필요가없고 심지어 mtime을 검사 할 필요가 없기 때문에 훨씬 빠르게 작동합니다. head없이이 코드를 실행하면 홈 폴더의 경우 몇 시간에서 1 초 미만까지 상당한 차이가 있음을 알 수 있습니다. (필자도 내 PC에서 파일을 완성 할 수 있을지 모르겠다. 내 홈 폴더에 수백만 개의 작은 파일이있다 ...)

+0

왜 파일을 올바르게 계산해야합니까? 중요한 것은 0 또는 0이 아닙니다. – Barmar

+0

@Barmar 끝까지 내 대답을 정말로 읽었습니까? 그렇습니다. 그러나 많은 프로그래머는 맹목적으로''wc -l''이 정확한 수의 파일을 제공 할 것이라고 생각할 수도 있습니다. 그래서 나는 이것을 분명히하고 싶었습니다. (그리고 파일을 세는 올바른 해결책은 거의 없습니다.) 나중에, 내 대답의 끝에서, 나는 적어도 하나의 파일이 있는지 더 나은 해결책을 제시했다. –

+0

다행스럽게도'find'는 출력을 버퍼링하지 않거나, 그 해결책은 종료하기 전에 많은 파일을 조사합니다. – Barmar

2
for i in */ 
do 
    if [ `find "$i" -type f -mtime -7 | wc -l` -gt 0 ] 
    then 7za a -t7z /mnt/HD_a2/encrypted/ul_doc/"${i%/}.7z" -p1234 -mhe "$i" 
    fi 
done 
+0

개행이있는 파일은 어떻게됩니까? –

+1

이것들이 작동합니다. 그것은 파일 이름을 사용하지 않고 단지'find'가 파일 이름을 나열하는지 검사합니다. – Barmar

+0

정확하지만, 모든 파일의''mtime''을 검사해야하기 때문에 여전히 비효율적입니다. –

관련 문제