문제

나는 많은 파일을 반복하고 그 중 일부를 호출하는 프로그램을 만들었습니다.

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를 제공하는 다른 고급 언어로 자신의 프로그램을 쓸 수도 있습니다.

하나의 옵션은 조가비 Python으로 작성된 SSH 클라이언트 및 서버 구현입니다. 트위스트 뼈대. 다른 프로토콜 (HTTP 또는 UNIX 도메인 소켓, FTP, SSH 등)을 통해 요청을 수락하는 도구를 작성하는 데 사용하고 장기 실행되는 SSH 연결을 통해 파일 전송을 트리거 할 수 있습니다. 실제로, 여러 SSH 연결 설정을 피하기 위해이 기술을 사용하는 여러 프로그램이 생산에 있습니다.

거기있었습니다 여기에서 매우 비슷한 질문입니다 몇 주 전에. 그만큼 받아 들여진 답변 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를 사용하여 슬로우가 아닌 방식으로 파일을 전송합니다.

간단하게 유지하고 이런 일을하는 작은 래퍼 스크립트를 작성하십시오.

  1. 파일을 타르십시오
  2. 타르 파일을 보내십시오
  3. 반대편에 untar

이 같은:

  1. tar -cvzf test.tgz 파일 ....
  2. scp test.tgz user@other.site.com :.
  3. ssh user@other.site.com tar -xzvf test.tgz

/요한

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top