stdin을 통해(ssh를 통해) 여러 파일 전달

stdin을 통해(ssh를 통해) 여러 파일 전달

원격 호스트에 프로그램이 있고 그 실행을 자동화해야 합니다. 동일한 머신에서 프로그램을 실행하는 명령은 다음과 같습니다.

/path/to/program -a file1.txt -b file2.txt

이 경우에는 프로그램 내에서 file1.txt및 가 각각 완전히 다른 용도로 사용되므로 함께 사용할 file2.txt수 없습니다 . cat하지만 내 경우에는 프로그램에 전달하려는 합계가 file1.txt내 장치에만 존재하고 프로그램을 실행해야 하는 호스트에는 존재하지 않습니다. file2.txtSSH를 통해 최소한 하나의 파일을 전달할 수 있다는 것을 알고 있습니다 stdin.

cat file1.txt | ssh host.name /path/to/program -a /dev/stdin -b file2.txt

하지만 호스트에 파일을 저장하는 것이 허용되지 않기 때문에 file2.txt호스트에 갈 수 있는 방법도 필요합니다. 환경 변수를 남용하고 창의적 cat으로 함께 사용하면 가능할 수도 있다고 생각 sed하지만, 이를 달성하기 위해 사용하는 방법을 이해하기에는 이러한 도구에 대해 충분히 알지 못합니다. 가능합니까? 달성하는 방법?

답변1

프로그램에 인수로 제공된 파일이 텍스트 파일이고 해당 내용을 제어할 수 있는 경우(여기에 표시되지 않는 줄을 알고 있음) 여기 문서를 여러 개 사용할 수 있습니다.

{
    echo "cat /dev/fd/3 3<<'EOT' /dev/fd/4 4<<'EOT' /dev/fd/5 5<<'EOT'"
    cat file1
    echo EOT
    cat file2
    echo EOT
    cat file3
    echo EOT
} | ssh user@host sh

다음은 cat파일 이름을 인수로 사용하는 명령의 예입니다. 다음과 같을 수도 있습니다:

echo "/path/to/prog -a /dev/fd/3 3<<'EOT' -b /dev/fd/4 4<<'EOT'

EOT각 콘텐츠를 각 파일에 나타나지 않는 콘텐츠로 개별적으로 교체하세요.

답변2

아마도 당신이 원하는 것이 아닐 수도 있지만... SSH가 연 파이프를 통해 타르볼을 보내는 것을 고려해 볼 수 있습니까?

당신은 전에 이렇게 말했습니다.

호스트에 파일을 저장할 수 없습니다.

쓰기 가능한 홈 디렉터리나 장기간 파일을 저장할 수 있는 편리한 위치가 없을 수도 있지만, 쓰기 가능한 위치가 없을 가능성은 거의 없으며 tmpfs특정 연결을 위한 임시 위치도 없을 것입니다.

많은 프로그램(libc 루틴 포함)에는 쓰기 가능 파일이 필요하므로 /tmp이를 사용할 가능성이 높습니다.

그런 다음 스크립트를 사용하여 tarball을 임시 디렉터리로 추출하고 프로그램을 실행한 다음 SSH 연결을 통해 정리할 수 있습니다.

그것은 다음과 같습니다:

$ tar cf - file1.txt file2.txt |
  ssh host.name '
      set -e
      tmpdir=$(mktemp -d -t tmp.XXXXXXXXXX)
      cleanup () { rm -rf "$tmpdir"; }
      trap cleanup EXIT
      cd "$tmpdir"
      tar xf -
      /path/to/program -a file1.txt -b file2.txt
  '

이를 위해서는 파일 경로와 고려해야 할 일부 극단적인 경우(테스트)에 특별한 주의가 필요할 수 있지만 일반적인 접근 방식이 작동합니다.

쓰기 가능한 디렉토리가 없는 경우 가능한 접근 방식은 program타르볼을 단일 입력으로 사용하고 해당 내용을 메모리로 추출하도록 수정하는 것입니다. 예를 들어 programPython 스크립트인 경우 tarfile내장 모듈을 사용하면 이와 같은 작업을 쉽게 수행할 수 있습니다.

답변3

TCP 수신기(아마도 더 높은 포트)를 설정할 수 있는 경우 두 번째 SSH 세션을 사용하여 두 번째 입력 소스를 설정할 수 있습니다 nc.

예:

서버( ~/script.bash)에 다음 스크립트가 있습니다.

#!/usr/bin/env bash
cat "$1" | tr a 1
nc localhost "$2" | tr '[:lower:]' '[:upper:]'

그리고 로컬에는 다음 두 파일이 있습니다.

$ cat a 
aaa
aaa
aaa
$ cat b
bbb
bbb
bbb

이제 먼저 두 번째 소스( $serv서버)를 시작합니다.

ssh "$serv" nc -l -p 2222 -q1 <b &

명령을 올바르게 실행합니다.

$ ssh "$serv" ./script.bash - 2222 <a
111
111
111
BBB
BBB
BBB
[1]+  Done                    ssh "$serv" nc -l -p 2222 -q1 < b

답변4

전달된 포트를 통해 허용되고 원격 시스템과 로컬 시스템 ssh모두에 액세스할 수 있는 경우 다음을 수행할 수 있습니다.wgetbusybox

mkdir /tmp/test; cd /tmp/test
echo 1st_file > 1st_file
echo 2nd_file > 2nd_file

busybox httpd -f -p 127.0.0.1:11080 &
ssh USER@HOST -R 10080:127.0.0.1:11080 '
        cat <(wget -q -O- http://localhost:10080/1st_file) \
            <(wget -q -O- http://localhost:10080/2nd_file)
'
kill $!

( cat두 개의 파일 매개변수가 있는 샘플 프로그램)

포트를 전달하는 기능만 -R필요합니다. http를 사용하는 대신 다른 방법을 사용할 수 있습니다. 예를 들어 및 옵션을 netcat지원하는 경우 :-d-N

nc -Nl localhost 11001 < 1st_file &
nc -Nl localhost 11002 < 2nd_file &
ssh USER@HOST -R 10001:localhost:11001 -R 10002:localhost:11002 '
        cat <(nc -d localhost 10001) <(nc -d localhost 10002)

<(...)원격 시스템의 로그인 셸이 ksh 또는 bash와 같은 것이 아닌 경우 프로세스 대체를 대체할 수 있는 방법이 있을 수 있습니다.

전체적으로 이것은 좋지 않습니다. 정확한 시스템/셸/구성/권한(아직 제공하지 않은)에 대한 더 나은 지식을 통해 더 똑똑한 솔루션을 만들 수 있습니다.

관련 정보