파일을 쓰는 중인지 확인합니까?


25

특정 디렉토리에서 tar 파일을 찾는 자동화 된 프로세스 (1 분 cron 스크립트를 통해)를 배포해야합니다. tar 파일이 발견되면 해당 위치로 압축이 풀린 후 tar 파일이 삭제됩니다.

tar 파일은 다른 서버에서 SSH를 통해이 서버로 자동 복사됩니다. 경우에 따라 tar 파일은 파일이 많은 매우 큰 파일입니다.

내가 겪을 것으로 예상되는 문제 : tar 파일을 서버에 복사하는 데 1 분 이상 걸리고 cron 스크립트가 1 분마다 한 번씩 실행되면 .tar.gz 파일을보고 시도합니다. tar 파일이 아직 작성중인 경우에도 압축을 해제하십시오.

bash 명령을 통해 파일이 현재 쓰고 있는지 또는 부분 파일인지 여부를 테스트하는 방법이 있습니까?

내가 생각한 한 가지 대안은 파일을 다른 파일 확장자 (예 :)로 복사 한 다음 전송이 완료 된 후 .tar.gz.part이름을 바꾸는 것이 었 .tar.gz습니다. 그러나 파일이 명령 줄에서 전체 파일인지 확인하는 간단한 방법이 있는지 알아 내려고 노력했습니다. 단서가 있습니까?


2
파일이 정확히 어떻게 전송됩니까? 예를 들어, rsync전송 중 (기본적으로) 임시 파일 이름을 사용 하고 파일이 완전히 전송 된 후에 만 파일 이름을 실제 파일 이름으로 바꿉니다.
Piskvor

답변:


12

파일의 이름을 바꾸는 것은 원자적인 작업이므로 업로드 후 이름 바꾸기를 수행하는 것은 간단하고 우아하며 오류가 발생하지 않습니다. 내가 생각할 수있는 또 다른 접근법 lsof | grep filename.tar.gz은 다른 프로세스가 파일에 액세스하고 있는지 확인하는 데 사용 하는 것입니다 .


7
( lsof filename.tar.gz보다 효율적이고 정확함 lsof | grep filename.tar.gz)
Rich

BTW, 파일 이름의 절대 경로 여야합니다
DennisLi

14

가장 좋은 방법은 lsof프로세스가 파일을 열 었는지 확인하는 데 사용 하는 것입니다.

#  lsof -f -- /var/log/syslog
COMMAND   PID   USER   FD   TYPE DEVICE SIZE/OFF  NODE NAME
rsyslogd 1520 syslog    1w   REG  252,2    72692 16719 /var/log/syslog

글을 쓰는 과정에 있는지 쉽게 알 수 없지만 글을 쓰는 경우 반드시 열려 있어야합니다.


편집 : 제안 된 솔루션을 구현하지 말고 실제 문제를 해결하십시오!

rsync를 사용하여 파일을 전송하십시오.

  rsync -e ssh remote:big.tar.gz .

이렇게하면 파일이 기존 파일 위에 복사되지 않고 .big.tar.gz.XXXXXX전송이 완료 될 때까지 임시 파일 ( ) 로 복사 된 다음 제자리로 이동됩니다.


6

조금 오래되었지만 대부분의 답변은 질문의 요점을 완전히 놓칩니다.

그러나 파일이 명령 줄에서 전체 파일인지 확인하는 간단한 방법이 있는지 알아 내려고 노력했습니다.

일반적으로 없습니다. 이를 결정하기에 충분한 정보가 없습니다.

파일이 닫혀 있는지 확인하는 것은 파일이 전체 인지 확인하는 것과 다릅니다 . 예를 들어, 전송 도중 연결이 끊어지면 파일이 "닫힙니다".

@Alex의 답변만이 맞습니다. 그리고 심지어 그는 lsof다소 사용하여 떨어졌다 .

파일이 완전히 전송되었는지 확인하려면 더 많은 데이터가 필요합니다. 같은 :

내가 생각한 한 가지 대안은 파일을 다른 파일 확장자 (예 :)로 복사 한 다음 전송이 완료 된 후 .tar.gz.part이름을 바꾸는 것이 었 .tar.gz습니다.

파일이 완전히 성공적으로 전송되었음을 알리는 완벽한 방법입니다. 동일한 파일 시스템 내에있는 한 파일을 한 디렉토리에서 다른 디렉토리로 이동할 수도 있습니다. 또는 발신자가 빈 filename.done파일을 보내 신호 완료를 보내도록합니다 .

그러나 모든 방법은 전송자가 성공적으로 전송되었음을 알리는 발신자에게 의존해야합니다. 발신자 만 해당 정보를 가지고 있기 때문입니다.

PDF와 같은 일부 파일 형식에는 파일이 완전한지 확인할 수있는 데이터가 있습니다. 그러나 거의 모든 파일을 열고 읽어야합니다.

lsof파일이 더 이상 열려 있지 않다는 것을 알려줄뿐입니다 . 더 이상 열려 있지 않은 이유를 알려주지 않습니다. 또한 파일 크기가 얼마나 큰지 알려줄 수 없습니다.


1
나는 이것을 충분히지지 할 수 없다. XY 문제를 해결하는 것이 좋습니다.
Beefster

5

이를 수행하는 가장 좋은 방법은 incron ( "inotify cron 시스템")을 사용하는 것입니다. 디렉토리 에서 inotify watch 를 설정하면 파일 조작을 알려줍니다. 이 경우 dir에 close_write가 있는지 감시해야합니다. 그러면 쓰기 후 파일이 닫히면 명령을 실행할 수 있습니다.


2

lsof가 파일이 어떤 모드에서 열려 있는지 감지 할 수있는 것처럼 보입니다.

lsof -f -- a_file
COMMAND   PID  USER   FD   TYPE DEVICE SIZE/OFF     NODE NAME
cat     52391 bob    1w   REG    1,2       15 19545007 a_file

1w가 어디 있는지보세요? 이는 파일 디스크립터 번호가 1이고 모드가 w 또는 쓰기임을 의미합니다.


FD필드 쇼 3r나를 위해 파일을 읽기 위해 열려있을 때.
Sopalajo de Arrierez

0

를 사용하면 결과 inotifywait를 얻을 수 있습니다. 명령을 실행하기 전에 파일 쓰기가 완료 될 때까지 기다릴 수 있습니다.

다음은 새 파일에 대한 폴더를 지속적으로 감시하고 파일 쓰기가 완료되면 루프에서 명령을 실행합니다.

WATCH_DIR=/directory/to/monitor
DEST_DIR=/x/y/z

/usr/bin/inotifywait --recursive --monitor --quiet -e moved_to -e close_write --format '%w%f' "$WATCH_DIR" | while read -r INPUT_FILE; do

mv "$0" "$DEST_DIR"

done

자세한 구성 옵션은 https://linux.die.net/man/1/inotifywatch를 참조 하십시오.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.