web-dev-qa-db-ja.com

stdinを介して(ssh経由で)複数のファイルを渡す

リモートホストにプログラムがあり、その実行を自動化する必要があります。コマンドはそのプログラムを同じマシンで実行し、次のようになります。

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

この場合、file1.txtfile2.txtはプログラム内でまったく異なるものに使用されるため、これらを一緒にcatすることはできません。ただし、私の場合、プログラムに渡したいfile1.txtfile2.txtは、プログラムを実行する必要のあるホストではなく、デバイスにのみ存在します。 stdinを介して渡すことで、SSH経由で少なくとも1つのファイルをフィードできることを知っています。

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

ただし、ホストにファイルを保存することは許可されていないため、file2.txtをそこに取得する方法も必要です。環境変数の悪用とcatsedのクリエイティブな併用によって可能になると思いますが、それらをどのように使用するかを理解するのに十分なツールを知りませんこれを達成します。それは可能ですか?

15
Green Cloak Guy

プログラムの引数として指定されたファイルがテキストファイルであり、その内容を制御できる場合(その中にはない行がわかっている場合)、複数のヒアドキュメントを使用できます。

{
    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を、それぞれのファイルで発生しないものに置き換えます。

18
mosvy

たぶん、あなたが望んでいるものではないかもしれません...しかし、sshによって開かれたパイプを介してtarballを送信することを検討してください。

あなたが言った:

ホストにファイルを保存することはできません。

長期的にファイルを保存するための書き込み可能なホームディレクトリやその他の便利な場所がない可能性がありますが、一時的な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を変更してtarballを単一の入力として受け取り、その内容をメモリに解凍することです。たとえば、programがPythonスクリプトである場合、組み込みのtarfileモジュールを使用すると、そのようなことを簡単に実現できます。

14
filbranden

TCPリスナー(より高いポートにすることもできます))を設定できる場合、2番目のSSHセッションを使用して、ncで2番目の入力ソースを確立できます。

例:

サーバー上にこのスクリプトがあります(~/script.bash):

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

そして、これらの2つのファイルがローカルにあります。

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

次に、最初に2番目のソース($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
5
user147505

コメント/tmpが書き込み可能であることが確立されているため、事前にファイルの1つをコピーするだけです。

scp -p file2.txt Host.name:/tmp/
ssh Host.name "/path/to/program -a /dev/stdin -b /tmp/file2.txt && rm /tmp/file2.txt" < file1.txt

これにより、正常に実行された後、コピーされたファイルもクリーンアップされます(成功に関係なく削除する場合は&&;に変更しますが、終了値が失われることに注意してください)。


それが許容できない場合は、/path/to/programまたは次のような単一の入力ストリームから2つのファイルを分離できるラッパーをいじることをお勧めします。

awk 'FNR == 1 && NR > 1 { printf "%c%c%c", 28, 28, 28 } 1' file1.txt file2.txt \
  | ssh Host.name /path/to/tweaked_program

これは ASCII情報セパレーター4 (ファイルセパレーター、FS)を使用して3倍にし、バイナリファイルが偶然その文字列を含む可能性を最小限に抑えます。次に、tweaked_programは、セパレータを指定して入力を分割し、保存された2つのファイルを変数として操作します。

もちろん、tarballを処理するためのライブラリーがある言語を使用している場合、より安全で明確なアプローチは、次のようにtarssh全体でそのようなコードにパイプすることです。

tar -zpc file1.txt file2.txt |ssh Host.name /path/to/tweaked_program

そして、あなたのtweaked_programは、アーカイブを解凍して開き、各ファイルを異なる変数に保存してから、変数に対して元のprogramのロジックを実行します。

2
Adam Katz

sshを介してポートを転送することが許可されていて、リモートマシンのwgetとローカルマシンのbusyboxにアクセスできる場合は、次のようにします。

_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 $!
_

(2つのファイル引数を取るサンプルプログラムとして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に似ていない場合は、<(...)プロセスの置換を置き換える方法がある場合があります。

全体として、これはそれほどすばらしいことではありません。正確なsystem/shells/config/permissions(ユーザーが提供していない)についてのより良い知識は、よりスマートなソリューションを可能にする可能性があります。

1
mosvy