원격에서 스키마의 최신 두 파일을 동기화합니다.

원격에서 스키마의 최신 두 파일을 동기화합니다.

서로 다른 환경에 있는 두 서버 간에 특정 스키마의 최신 두 파일을 동기화하고 싶습니다.

drwxrwxr-x 2 transfer transfer          4096 28. Nov 13:05 .
drwxr-xr-x 7 transfer transfer          4096 28. Nov 13:05 ..
-rw-rw-r-- 1 transfer transfer   11151643678 28. Nov 12:46 test_28-11-2023.dmp.gz
-rw-rw-r-- 1 transfer transfer         29789 28. Nov 13:04 test_28-11-2023.log
-rw-r--r-- 1 transfer transfer   10770251760 28. Nov 13:00 test_anonym_19-11-2023.dmp.gz
-rw-r--r-- 1 transfer transfer         48408 28. Nov 13:02 test_anonym_19-11-2023.log
-rw-r--r-- 1 transfer transfer    9329096219 28. Nov 13:03 test_anonym_21-11-2023.dmp.gz
-rw-r--r-- 1 transfer transfer         48407 28. Nov 13:03 test_anonym_21-11-2023.log

최신 패턴만 전송하고 싶기 때문에 *.gz다음을 수행하여 패턴을 식별할 수 있습니다.*.log\.\/test_anonym_.*\.*

user@host:~/folder$ find . -type f -regex '\.\/test_anonym_.*\.*' | sort -r | head -n 2
./test_anonym_21-11-2023.log
./test_anonym_21-11-2023.dmp.gz

또는 다음과 같이 리모콘에서 직접 식별할 수 있습니다 ssh(매우 효과적입니다).

user@host:~/folder$ ssh -qx user@host "ls -t /home/user/folder | sort -r | head -n 2"
test_anonym_21-11-2023.log
test_anonym_21-11-2023.dmp.gz

다음 rsync명령은 한 가지 파일 형식에 대해서만 모드를 사용하고 두 가지 형식의 최신 파일을 인식하지 못하기 때문에 너무 많이 전송합니다.

user@host:~/folder$ rsync -av --stats --include='test_anonym_*.gz' --exclude='test_*.*' user@host:/home/user/folder/ /home/user/folder/

test_anonym_19-11-2023.dmp.gz
test_anonym_21-11-2023.dmp.gz

많은 매뉴얼 페이지와 유사한 게시물을 살펴본 후 ssh및 를 함께 사용해 보았지만 완료되지 않은 단계에서 실패했습니다.rsyncssh

ssh user@host "ls -t /home/user/folder/ | sort -r | head -n 2" | rsync -0 --stats --files-from=- -av user@host:/home/user/folder/ /home/user/folder/

rsyncwith 옵션을 사용해 보았지만 --files-from=두 예제의 구문이 확실하지 않기 때문에 실패했습니다.

rsync -a --stats --files-from=<(ssh user@host 'find . -type f -regex '\./test_anonym_.*\.*' | sort -r | head -n 2') --exclude='test_*.*' user@host:/home/user/folder/ /home/folder/folder/

rsync -a --stats --files-from=<(find . -type f -regex '\.\/test_anonym_.*\.*' | sort -r | head -n 2) --exclude='test_*.*' user@host:/home/user/folder/ /home/folder/folder/

필요한 파일을 찾고 동기화하기 위해 모든 것을 하나로 모으는 방법(또는 가능한 경우)을 잘 모르겠습니다. 지금은 정말 막혔습니다. 어떻게 해야 하나요? 나는 그것을 내 워크스테이션에서 사용하고 zsh, 내 리모콘에서도 사용합니다 bash.

여기서 내 기대를 다시 한번 말씀드리자면, 저는 원격에서 내 패턴과 일치하고 해당 유형의 최신 두 파일 인 iE 및 Witch의 서로 다른 유형의 두 파일을 rsync원합니다 .sshtest_anonym_21-11-2023.logtest_anonym_21-11-2023.dmp.gz

답변1

GNU 도구가 있는 경우 이를 사용하여 find가장 최근에 수정된 두 파일을 식별하고 해당 파일만 전송할 수 있습니다. 원격 호스트에서 파일을 추출해야 하므로 프로세스가 조금 더 복잡하지만 이는 ssh더 많은 참여가 필요함을 의미합니다.

가장 최근에 수정된 두 파일이 전송될 파일 쌍이라고 가정할 수 있고 GNU 확장자(또는 유사한)를 가진 도구가 있는 경우:

ssh -qn remoteHost "find folder -name 'test_anonym_*' -printf '%T@ %p\0'" |
    sort -z -k1,1rn |
    head -z -n2 |
    cut -z -d' ' -f2- |
    rsync --dry-run -av --files-from - --from0 remoteHost: "$HOME/folder"

GNU 도구가 없으면 예상치 못한 파일 이름에 주의해야 합니다. 하지만 이 파이프라인은 다음에 배치할 파일 이름을 제어할 수 있는 한 작동합니다 folder.

ssh -qn remoteHost ls -t folder |
    head -n2 |
    rsync --dry-run -av --files-from - --from0 remoteHost:folder/ "$HOME/folder"

두 경우 모두 --dry-run코드가 기대한 대로 작동하고 있다고 만족스러우면 코드를 제거하세요.

파일만 보장할 수 dmp.gz있고 관련 파일을 추출하려는 경우 log상황은 더 복잡해집니다 . 그러나 귀하의 문제에는 이것이 필요하지 않은 것 같습니다.

답변2

대상 사용자의 로그인 쉘이 remoteHostzsh인 경우 다음을 수행하십시오.

rsync --old-args 'remoteHost:folder/test_anonym*.(log|gz)(.om[1,2])' ~/folder/

이 동작이 더 이상 기본값이 아닌 최신 버전에서는 필수이며 --old-args호출하는 원격 셸 명령줄에서 있는 그대로 전달되고 셸은 이름에서 가장 최근 파일 두 개와 일치하는 glob을 다음으로 시작 또는 및로 확장합니다. 또는로 끝납니다.rsyncfolder/test_anonym*.(log|gz)(.om[1,2])rsync --serverfoldertest_anonym.gz.log

다음 명령을 실행하면 --old-args사용 여부와 사용 여부에 따른 동작의 차이를 발견할 수 있습니다.--protect-argsrsyncstrace -e execve

$ strace -fe execve rsync --old-args 'remoteHost:folder/test_anonym*.(log|gz)(.om[1,2])' ~/folder/
[...]
[pid  8483] execve("/bin/ssh", ["ssh", "remoteHost", "rsync", "--server", "--sender", "-e.LsfxCIvu", ".", "folder/test_anonym*.(log|gz)(.om"...], 0x7ffceb4e2cf0 /* 52 vars */) = 0
[...]

Arg가 수정 없이 통과되었습니다.

$ strace -fe execve rsync 'remoteHost:folder/test_anonym*.(log|gz)(.om[1,2])' ~/folder/
[...]
[pid  8489] execve("/bin/ssh", ["ssh", "remoteHost", "rsync", "--server", "--sender", "-e.LsfxCIvu", ".", "folder/test_anonym*.\\(log\\|gz\\)\\"...], 0x7ffc5bced518 /* 52 vars */) = 0
[...]

\원격 셸에 유효한지 여부에 관계없이 일부 문자는 이스케이프됩니다 .

$ strace -fe execve rsync --protect-args  'remoteHost:folder/test_anonym*.(log|gz)(.om[1,2])' ~/folder/
[...]
[pid  8507] execve("/bin/ssh", ["ssh", "remoteHost", "rsync", "--server", "--sender", "-se.LsfxCIvu"], 0x7ffc404a9900 /* 52 vars */) = 0
[...]

arg는 셸 명령줄에서 전달되지 않지만 최신 rsync 프로토콜에서는 대역 내로 전달됩니다. 일반적으로 이것이 가장 안전하지만 쉘의 고급 와일드카드를 사용할 수 없습니다.

zsh가 원격 호스트에 설치되어 있지만 사용자의 로그인 셸이 bash인 경우 다음 트릭을 사용하여 zsh가 rsync 서버 명령을 실행하도록 bash를 설득할 수 있습니다.

rsync --rsync-path='zsh -c "${BASH_EXECUTION_STRING#*\#\ }" # rsync' \
  --old-args 'remoteHost:folder/test_anonym*.(log|gz)(.om[1,2])' ~/folder/

원격 호스트의 bash는 다음을 평가하라는 요청을 받습니다:

zsh -c "${BASH_EXECUTION_STRING#*\#\ }" # rsync --server --sender -e.LsfxCIvu . folder/test_anonym*.(log|gz)(.om[1,2])

전체 rsync --server...명령은 주석으로만 처리됩니다.

$BASH_EXECUTION_STRINGbash는 자동으로 bash를 실행 중인 인라인 스크립트로 설정하고 처음 나타날 때까지 모든 것을 제거하므로 #다음과 같이 zsh설명됩니다.

rsync --server --sender -e.LsfxCIvu . folder/test_anonym*.(log|gz)(.om[1,2])

필요하지 않다면동기화능력이 있지만 rsync이러한 파일만 전송하면 더 쉬울 수 있습니다.

ssh remoteHost zsh << 'EOF' | (cd ~/folder && tar zxpvf -)
  cd folder &&
    tar zcf - test_anonym*.(log|gz)(.om[1,2])
EOF

답변3

내 원래 질문 :

"다른 환경에 있는 두 서버 간에 특정 스키마의 최신 두 파일을 동기화하고 싶습니다."

내 (전송) 호스트 서버에는 최신 파일이 포함되어 있습니다.

drwxrwxr-x 2 transfer 4,0K 26. Mär 13:30 .
drwxr-xr-x 6 transfer 4,0K 20. Mär 11:01 ..
-rw-rw-r-- 1 transfer    0 26. Mär 13:30 test_26-03-2024.dmp.gz
-rw-rw-r-- 1 transfer    0 26. Mär 13:30 test_26-03-2024.log
-rw-rw-r-- 1 transfer    0 28. Nov 12:46 test_28-11-2023.dmp.gz
-rw-rw-r-- 1 transfer   21 28. Nov 13:04 test_28-11-2023.log
-rw-rw-r-- 1 transfer   0 26. Mär 13:30 test_anonym_17-03-2024.dmp.gz
-rw-rw-r-- 1 transfer    0 26. Mär 13:30 test_anonym_17-03-2024.log
-rw-r--r-- 1 transfer    0 28. Nov 13:00 test_anonym_19-11-2023.dmp.gz
-rw-r--r-- 1 transfer    5 29. Jan 13:35 test_anonym_19-11-2023.log
-rw-r--r-- 1 transfer    0 28. Nov 13:03 test_anonym_21-11-2023.dmp.gz
-rw-r--r-- 1 transfer  497 29. Jan 13:36 test_anonym_21-11-2023.log
-rw-rw-r-- 1 transfer    0 29. Jan 13:38 test_anonym_29-01-2024.dmp.gz
-rw-rw-r-- 1 transfer  201 29. Jan 13:37 test_anonym_29-01-2024.log
user@transfer:~/folder$ 

내 문제에 대한 해결책:

내 (devops) 다른 서버에서 이름 지정 패턴과 파일 유형을 사용하여 두 개의 최신 파일을 식별 test_anonym_*.*하고 출력을 텍스트 파일로 저장했습니다..log.dmp.gz

user@devops:~$ ssh -qx user@transfer 'ls -tr /home/user/folder | sort -k 8,8n -k 6,6M | grep test_anonym_* | head -n 2' > output.txt
...
user@devops:~$ nl output.txt 
     1  test_anonym_17-03-2024.dmp.gz
     2  test_anonym_17-03-2024.log

이제 rsync텍스트 파일에 포함된 파일을 다른 서버로 보낼 수 있습니다.

user@devops:~$ rsync -arv --stats --include-from=output.txt --exclude=* user@transfer:folder/ ./folder/
user@transfer's password: 
receiving incremental file list
./
test_anonym_17-03-2024.dmp.gz
test_anonym_17-03-2024.log
...
sent 139 bytes  received 211 bytes  100,00 bytes/sec
total size is 0  speedup is 0,00

올바른 파일이 전송되었으며 주요 문제가 해결되었습니다.

user@devops:~$ ls -la folder/
drwxrwxr-x 2 user user 4096 26. Mär 13:30 .
drwxr-xr-x 4 user user 4096 26. Mär 14:55 ..
-rw-rw-r-- 1 user user    0 26. Mär 13:30 test_anonym_17-03-2024.dmp.gz
-rw-rw-r-- 1 user user    0 26. Mär 13:30 test_anonym_17-03-2024.log

가져서 좋다: 이제 해결책은 sshrsync명령을 하나의 명령으로 파이프하거나 , 및 를 저장 하는 것 입니다 ls.sortgrepheadtmp하지만 --include-from=이를 지지해줄 사람은 아무도 없는 것 같습니다.

관련 정보