서로 다른 환경에 있는 두 서버 간에 특정 스키마의 최신 두 파일을 동기화하고 싶습니다.
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
및 를 함께 사용해 보았지만 완료되지 않은 단계에서 실패했습니다.rsync
ssh
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/
rsync
with 옵션을 사용해 보았지만 --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
원합니다 .ssh
test_anonym_21-11-2023.log
test_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
대상 사용자의 로그인 쉘이 remoteHost
zsh인 경우 다음을 수행하십시오.
rsync --old-args 'remoteHost:folder/test_anonym*.(log|gz)(.om[1,2])' ~/folder/
이 동작이 더 이상 기본값이 아닌 최신 버전에서는 필수이며 --old-args
호출하는 원격 셸 명령줄에서 있는 그대로 전달되고 셸은 이름에서 가장 최근 파일 두 개와 일치하는 glob을 다음으로 시작 또는 및로 확장합니다. 또는로 끝납니다.rsync
folder/test_anonym*.(log|gz)(.om[1,2])
rsync --server
folder
test_anonym
.gz
.log
다음 명령을 실행하면 --old-args
사용 여부와 사용 여부에 따른 동작의 차이를 발견할 수 있습니다.--protect-args
rsync
strace -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_STRING
bash는 자동으로 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
가져서 좋다:
이제 해결책은 ssh
및 rsync
명령을 하나의 명령으로 파이프하거나 , 및 를 저장 하는 것 입니다 ls
.sort
grep
head
tmp하지만 --include-from=
이를 지지해줄 사람은 아무도 없는 것 같습니다.