요청시 SSH를 통해 파일을 전송하기 위해 발신자 및 수신자?
-
21-08-2019 - |
문제
나는 많은 파일을 반복하고 그 중 일부를 호출하는 프로그램을 만들었습니다.
scp <file> user@host:<remotefile>
그러나 필자의 경우 전송 해야하는 수천 개의 작은 파일이있을 수 있으며 SCP는 각각에 대해 새로운 SSH 연결을 열고 있으며, 이는 약간의 오버 헤드가 있습니다.
연결을 유지하는 한 프로세스를 유지하는 솔루션이없고 단일 파일을 통해 복사하기 위해 "요청"을 보낼 수있는 솔루션이 없는지 궁금합니다.
이상적으로는 일부 발신자 및 수신자 프로그램의 조합을 찾고있어 처음에 단일 프로세스 (1)를 시작할 수 있습니다.
ssh user@host receiverprogram
각 파일에 대해 명령을 호출합니다 (2).
senderprogram <file> <remotefile>
(2)의 출력을 (1)의 입력에 파이프하면 파일이 전송됩니다. 결국, 나는 단지 프로세스를 보낼 수 있습니다 (1) 일부 신호를 종료 할 수 있습니다.
바람직하게는 발신자 및 수신자 프로그램은 UNIX의 오픈 소스 C 프로그램입니다. 파이프 대신 소켓이나 다른 창의적인 솔루션을 사용하여 통신 할 수 있습니다.
그러나 그것은입니다 중요한 제약 내가 반복하는 순간 각 파일이 전송됩니다. 파일 목록을 수집 한 다음 하나의 인스턴스를 호출하는 것은 허용되지 않습니다. scp
끝에 모든 파일을 한 번에 전송합니다. 또한 수신 호스트에 대한 간단한 쉘 액세스 만 있습니다.
업데이트: SSH의 멀티플렉싱 기능을 사용하여 연결 오버 헤드 문제에 대한 솔루션을 찾았습니다. 아래의 답변을 참조하십시오. 그러나 나는 여기에 설명 된대로 발신자/수신자 프로그램이 있는지 궁금하기 때문에 현상금을 시작하고 있습니다. 예를 들어 xmodem/ymodem/zmodem을 사용할 수있는 것이 존재해야합니까?
해결책
이런 식으로 효과가 있으며 다른 것들에 대해서는이 일반적인 접근 방식이 어느 정도 옳습니다.
(
iterate over file list
for each matching file
echo filename
) | cpio -H newc -o | ssh remotehost cd location \&\& | cpio -H newc -imud
다른 팁
다른 각도에서 해결책을 찾았습니다. 부터 버전 3.9, OpenSsh는 지원합니다 세션 다중화: 단일 연결은 여러 로그인 또는 파일 전송 세션을 수행 할 수 있습니다. 이것은 연결 당 설정 비용을 피합니다.
질문의 경우 먼저 컨트롤 마스터를 설정하는 것과 연결을 열 수 있습니다 (-M
) 소켓 (-S
) 특정 위치에서. 세션이 필요하지 않습니다 (-N
).
ssh user@host -M -S /tmp/%r@%h:%p -N
다음으로 호출 할 수 있습니다 scp
각 파일에 대해 동일한 소켓을 사용하도록 지시합니다.
scp -o 'ControlPath /tmp/%r@%h:%p' <file> user@host:<remotefile>
이 명령은 거의 즉시 복사를 시작합니다!
일반 SSH 연결에는 제어 소켓을 사용할 수도 있고 즉시 열 수 있습니다.
ssh user@host -S /tmp/%r@%h:%p
컨트롤 소켓을 더 이상 사용할 수 없으면 (예 : 마스터를 죽였기 때문에) 이것은 정상적인 연결로 돌아갑니다. 자세한 내용은 다음에 확인할 수 있습니다 이 기사.
SCP 대신 SFTP를 사용하고 배치 모드로 배치하는 것이 좋습니다. 배치 명령 파일을 파이프 또는 유닉스 도메인 소켓으로 만들고 실행하려는대로 사료 명령을 제공하십시오.
이것에 대한 보안은 클라이언트 끝에서 약간 까다로울 수 있습니다.
당신은 시도 했습니까? sshfs
? 당신은 할 수 있습니다 :
sshfs remote_user@remote_host:/remote_dir /mnt/local_dir
어디에
/remote_dir
당신이 당신이/mnt/local_dir
지역 마운트 위치였습니다
이 설정을 사용하면 그냥 할 수 있습니다 cp
파일에 local_dir
그리고 그것은 전송 될 것입니다 sftp
에게 remote_host
그것에 remote_dir
단일 연결이 있으므로 오버 헤드가 거의 없습니다.
깃발을 사용해야 할 수도 있습니다 -o ServerAliveInterval=15
유지하려면 무기한 연결
당신은 필요합니다 fuse
로컬로 설치 및 SSH 서버 지원 (및 구성) sftp
당신은 이것을 찾고있을 수 있습니다 :ZSSH
ZSSH (ZMODEM SSH)는 SPH (Secure Shell)을 사용하는 동안 파일을 원격 시스템으로 대화식으로 전송하는 프로그램입니다. 그것은 SCP에 대한 편리한 대안으로, 다른 세션을 열지 않고도 파일을 전송하고 스스로를 다시 인증 할 수 있도록합니다.
모든 파일을 수집하여 단일 디렉토리 (또는 디렉토리의 계층)를 보낼 수있는 경우 RSYNC를 사용하십시오.
단일 장소에 모든 파일이없는 경우, 달성하려는 내용과 모든 파일을 아카이브에 포장하고이를 보낼 수없는 이유에 대한 정보를 더 제공하십시오. 각 파일이 즉시 전송되는 것이 왜 그렇게 중요합니까? 파일이 짧은 지연으로 전송 된 경우 (4K 분량의 데이터가 축적되었을 때와 같이) 괜찮습니까?
좋은 작은 문제입니다. 사전 포장 된 솔루션을 알지 못하지만 간단한 쉘 스크립트로 많은 일을 할 수 있습니다. 수신기에서 이것을 시도 할 것입니다.
#!/bin/ksh
# this is receiverprogram
while true
do
typeset -i length
read filename # read filename sent by sender below
read size # read size of file sent
read -N $size contents # read all the bytes of the file
print -n "$contents" > "$filename"
done
발신자 쪽에서는 이름이 지정된 파이프를 만들고 파이프에서 읽습니다.
mkfifo $HOME/my-connection
ssh remotehost receiver-script < $HOME/my-connection
그런 다음 파일을 보내려면이 스크립트를 사용해 보겠습니다
#!/bin/ksh
# this is senderprogram
FIFO=$HOME/my-connection
localname="$1"
remotename="$2"
print "$remotename" > $FIFO
size=$(stat -c %s "$localname")
print "$size" > $FIFO
cat "$localname" > $FIFO
파일 크기가 크면 한 번에 읽고 싶지 않을 것입니다.
BUFSIZ=8192
rm -f "$filename"
while ((size >= BUFSIZ)); do
read -N $BUFSIZE buffer
print -n "$buffer" >> "$filename"
size=$((size - BUFSIZ))
done
read -N $size buffer
print -n "$contents" >> "$filename"
결국 당신은 스크립트를 확장하여 통과 할 수 있습니다. chmod
그리고 chgrp
명령. 전송 코드를 신뢰하기 때문에 수신기가 단순히 쉘을 호출하도록 구조화하는 것이 가장 쉬운 일입니다. eval
각 줄에서 다음과 같은 물건을 보내십시오
print filename='"'"$remotename"'"' > $FIFO
print "read_and_copy_bytes " '$filename' "$size" > $FIFO
그런 다음 로컬 기능을 정의하십시오 read_and_copy_bytes
. 인용을 올바르게 얻는 것은 곰이지만 그렇지 않으면 간단해야합니다.
물론,이 중 어느 것도 테스트되지 않았습니다! 그러나 나는 그것이 당신에게 유용한 아이디어를 제공하기를 바랍니다.
타르 타르처럼 보입니까? 출력을 SSH로 파이프하고 다른쪽에는 SSH 출력을 TAR로 다시 파이프합니다.
Gnome 데스크탑은 SFTP (SSH)를 통해 공유에 액세스 할 때 단일 SSH 연결을 사용한다고 생각합니다. 이런 식으로 원격 공유에 액세스 할 때 단일 SSH 프로세스를 볼 수 있기 때문에 이것이 일어나고있는 일이라고 생각합니다. 따라서 이것이 사실이라면이 목적을 위해 동일한 프로그램을 사용할 수 있어야합니다.
그놈의 새로운 버전은 GVF를 사용했습니다 지오 다른 백엔드를 통해 모든 종류의 I/O를 수행하기 위해. Ubuntu 패키지 GVFS-Bin은 명령 줄에서 백엔드를 조작 할 수있는 다양한 명령 줄 유틸리티를 제공합니다.
먼저 SSH 폴더를 장착해야합니다.
gvfs-mount sftp : // user@host/
그런 다음 GVFS-Copy를 사용하여 파일을 복사 할 수 있습니다. 모든 파일 전송은 단일 SSH 프로세스를 통해 수행 될 것이라고 생각합니다. PS를 사용하여 사용되는 프로세스를 확인할 수도 있습니다.
더 모험적인 느낌이 들면 C 또는 GIO에 API를 제공하는 다른 고급 언어로 자신의 프로그램을 쓸 수도 있습니다.
거기있었습니다 여기에서 매우 비슷한 질문입니다 몇 주 전에. 그만큼 받아 들여진 답변 SSH가 원격 기계에 SSH를 할 때 터널을 열고 SCP 전송에 해당 터널을 사용하도록 제안했습니다.
Perhapse curlftpfs 유효한 솔루션 일 수 있습니다.
SFTP를 통해 외부 컴퓨터의 폴더를 컴퓨터에 마운트 한 것 같습니다. 완료되면 정규를 사용할 수 있어야합니다. cp
명령과 모든 것이 안전하게 이루어집니다.
불행히도 나는 그것을 직접 테스트 할 수 없었지만 그것이 나중에 효과가 있는지 알려주세요!
편집 1 : 나는 그것을 다운로드하고 테스트 할 수있었습니다. 내가 걱정하면서 클라이언트에 FTP 서버가 있어야합니다. 하지만, 나는 당신이 찾고있는 것과 정확히 같은 개념을 가진 다른 프로그램을 발견했습니다. sshfs
특수 서버없이 클라이언트 컴퓨터에 연결할 수 있습니다. 폴더 중 하나를 마운트 한 후에는 일반을 사용할 수 있습니다. cp
필요한 파일을 더 많이 이동하도록 명령. 일단 당신이 끝나면, 그것은 미소가되어야합니다. umount /path/to/mounted/folder
. 이것이 어떻게 작동하는지 알려주세요!
rsync -avlzp user@remotemachine:/path/to/files /path/to/this/folder
이것은 SSH를 사용하여 슬로우가 아닌 방식으로 파일을 전송합니다.
간단하게 유지하고 이런 일을하는 작은 래퍼 스크립트를 작성하십시오.
- 파일을 타르십시오
- 타르 파일을 보내십시오
- 반대편에 untar
이 같은:
- tar -cvzf test.tgz 파일 ....
- scp test.tgz user@other.site.com :.
- ssh user@other.site.com tar -xzvf test.tgz
/요한