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

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

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

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

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

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

하지만 호스트에 파일을 저장하는 것이 허용되지 않기 때문에 file2.txt호스트에도 파일을 가져올 수 있는 방법이 필요합니다. 환경 변수를 남용하고 catand 를 함께 창의적으로 사용하면 가능할 수도 있다고 생각 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와 유사하지 않은 경우 프로세스 대체를 대체하는 방법이 있을 수 있습니다 .

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

관련 정보