![Bash 스크립트의 명령을 완료하려면 어떻게 해야 합니까? (cp에 의해 잘린 파일)](https://linux55.com/image/151536/Bash%20%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8%EC%9D%98%20%EB%AA%85%EB%A0%B9%EC%9D%84%20%EC%99%84%EB%A3%8C%ED%95%98%EB%A0%A4%EB%A9%B4%20%EC%96%B4%EB%96%BB%EA%B2%8C%20%ED%95%B4%EC%95%BC%20%ED%95%A9%EB%8B%88%EA%B9%8C%3F%20(cp%EC%97%90%20%EC%9D%98%ED%95%B4%20%EC%9E%98%EB%A6%B0%20%ED%8C%8C%EC%9D%BC).png)
backupname.tar.gz
매 시간마다 디렉터리에서 파일을 받는 서버가 있습니다 ./home/my_user/drop
incron 유틸리티를 설치하고 /drop에 새 파일이 나타날 때 incrontab -e 항목을 사용하여 스크립트를 실행했습니다.
스크립트는 다음과 같습니다.
#!/bin/sh
#
# First clear the 2 immediate use directories
rm /home/my_user/local_ready/*
wait
sleep 1
rm /home/my_user/local_restore/*
wait
sleep1
# Copy the file from the /drop /local_ready
cp /home/my_user/drop/*.tar.gz /home/my_user/local_ready/
wait
sleep 5
# Now move the file to the /current folder
mv /home/my_user/drop/*.tar.gz /home/my_user/current/
wait
sleep 1
# Next we delete any stray files dropped that are not
# of the target type so we can keep /drop clean.
rm /home/my_user/drop/*
wait
sleep 1
# Un-Tar the files into the /local_restore directory
tar -xzf /home/my_user/local_ready/*.tar.gz -C /home/my_user/local_restore/
wait
sleep 1
# This should complete the movement of files
내가 겪고 있는 문제는 /local_restore
스크립트의 다음 명령으로 인해 명령이 중단되는 것처럼 디렉터리에 복사된 파일이 잘린다는 것입니다 cp
.
먼저 작동하도록 하기 위해 sleep 명령을 추가한 다음 스크립트의 각 명령 뒤에 wait 명령을 추가하여 작동하게 만들었습니다. 이렇게 하면 cp 명령이 파일 복사를 완료할 때까지 모든 것이 대기하게 될 것이라고 생각했습니다. 장소.
명령이 성공적으로 체인에 파일을 배치하는 tar
명령에 의존하기 때문에 명령이 작동하는지 조차 알 수 없습니다 . cp
파일 중 하나의 압축을 풀기 위한 명령만 사용하여 실행한 테스트에 따르면 스크립트가 종료되기 전에는 완료되지 않을 것으로 예상됩니다. 적어도 그것은 타이밍 이론을 테스트하는 데 사용한 또 다른 3선 테스트에서 일어난 일입니다.
그런데... mv
명령이 제대로 작동하고 전체 파일이 예상대로 이동합니다.
스크립트 내에서 실행되는 명령이 작업을 완료하지 못하는 이유를 누구나 알 수 있습니까?
incrontab 항목의 내용을 표시하라는 요청을 받았으므로 다음과 같습니다.
/home/my_user/drop/ IN_CREATE /home/my_user/bin/cycle_backups
(cycle_backups는 분명히 스크립트 파일의 이름입니다)
Ubuntu 16.04 LTS를 실행하고 10GB의 메모리와 100GB 이상의 디스크 공간을 갖춘 KVM 유형의 VPS 클라우드 서버입니다. 파일이 삭제되면 시스템 유휴 외에 서버가 수행하는 유일한 작업입니다!
내 서버가 약간 느리다는 것을 인정하므로 200mb 파일을 다른 디렉터리에 복사하려고 할 때 명령줄에서 올바르게 수행하더라도 완료하는 데 1~2초가 걸립니다.
문제를 설명할 수 없어서 해결책을 찾는 것이 더욱 어렵습니다.
공정한 경고: 제가 이 분야에 최고는 아니지만 달성하는 것이 불가능한 일이라고 생각하지 않습니다.
답변1
wait
백그라운드 작업이 없으므로 모든 호출은 스크립트에서 아무 작업도 수행하지 않습니다. 이 콘텐츠는 안전하게 삭제할 수 있습니다.
에 대한 호출도 제거하겠습니다 sleep
. 이 시점에서는 스크립트 실행만 지연됩니다. 그럼에도 불구하고 이전 명령이 올바르게 완료될 때까지 명령은 시작되지 않습니다. sleep1
"명령을 찾을 수 없음" 오류가 발생할 수도 있습니다 .
귀하의 스크립트에서 볼 수 있는 유일한 실제 문제는 마지막 호출입니다 tar
.
tar -xzf /home/my_user/local_ready/*.tar.gz -C /home/my_user/local_restore/
에 여러 아카이브가 있는 경우 /home/my_user/local_ready
이 명령은 첫 번째 아카이브를 추출하고 해당 아카이브에서 다른 아카이브의 이름을 추출하려고 시도합니다. 이 -f
로고는하나의아카이브이며 실제로 여러 아카이브를 한 번에 추출할 수는 없습니다.
대신 루프를 사용하세요.
for archive in /home/my_user/local_ready/*.tar.gz; do
tar -xzf "$archive" -C /home/my_user/local_restore/
done
나는 가지고있다무시당하다이 스크립트가 자체와 동시에 실행되면 어떤 일이 발생할지 생각해 보세요. 새 파일이 나타날 때 스크립트를 실행하는 몇 가지 도구가 있다고 언급했지만 두 개 이상의 파일이 동시에 나타날 경우 어떤 일이 발생하는지 명확하지 않습니다. 스크립트가 처리 중이므로모두단일 호출로 파일을 전송하는 경우 동시에 실행되는 두 개의 스크립트가 서로의 발가락을 밟을 가능성이 높다고 확신합니다.
개인적으로 저는 아마도 5분마다 스크립트를 실행했을 것입니다. 또는 특정 형태의 잠금을 사용하여 스크립트의 다른 복사본이 이미 실행 중인 동안 스크립트가 실행되지 않도록 합니다("쉘 스크립트의 잠금이 정확합니까?").
다음은 제가 직접 작성한 코드입니다(어떤 종류의 잠금도 사용하지 않음).
#!/bin/sh -e
cd /home/my_user
# clear directories
rm -f local_ready/*
rm -f local_restore/*
# Alternatively, remove directories completely
# to also get rid of hidden files etc.:
#
# rm -rf local_ready; mkdir local_ready
# rm -rf local_restore; mkdir local_restore
# handle the archives, one by one
for archive in drop/*.tar.gz; do
tar -xzf "$archive" -C local_restore
cp "$archive" current
mv "$archive" local_ready
done
그러면 이름이 숨겨지지 않은 디렉터리가 지워지고 각 아카이브가 추출됩니다. 아카이브를 추출한 후 디렉토리에 복사한 local_ready
다음 아카이브를 drop
에서 이동합니다 current
.
나는 이를 사용 sh -e
하여 오류 발생 시 스크립트를 종료하고 스크립트의 긴 경로를 피하기 위해 디렉터리 cd
로 이동합니다 (이렇게 하면 나중에 전체 작업을 하위 디렉터리나 다른 곳으로 쉽게 이동할 수 있습니다). /home/my_user
나는 이러한 디렉토리를 지우곤 했는데 , rm -f
glob이 아무 것도 확장되지 않으면 rm
불평을 하곤 했습니다 .*
분명히 아카이브 복사 및 추출을 별도로 처리할 수도 있습니다.
cp drop/*.tar.gz current
mv drop/*.tar.gz local_ready
for archive in local_ready/*.tar.gz; do
tar -xzf "$archive" -C local_restore
done
local_ready
공간을 절약하려면 다음의 하드 링크와 파일을 살펴보는 것이 좋습니다 current
.
mv drop/*.tar.gz local_ready
for archive in local_ready/*.tar.gz; do
ln "$archive" current
tar -xzf "$archive" -C local_restore
done
답변2
마스크를 IN_CLOSE_WRITE로 변경해야 합니다.