1つのCentOSサーバー上のstdout
を別のCentOSサーバー上のstdin
にパイプする必要があります。これは可能ですか?
ScottPack、MikeyB、jofelのすべてに有効な答えがあります。私の質問はセキュリティを要件として指定していませんが、安全であることが常にいいので、スコットに回答を与えました。ただし、他の2人のフェローの提案も機能します。
これは恥ずかしくないイエスです。
ssh
を使用してリモートサーバーでコマンドを実行すると、ある種の豪華な内部入出力リダイレクトが実行されます。実際、これはOpenSSHの微妙に優れた機能の1つだと思います。具体的には、ssh
を使用してリモートシステムで任意のコマンドを実行する場合、sshはSTDIN
およびSTDOUT
を実行中のコマンドのコマンドにマッピングします。
例として、バックアップtarballを作成したいが、ローカルに保存したくない、またはできない場合を想定してみましょう。この構文を少し見てみましょう。
$ tar -cf - /path/to/backup/dir | ssh remotehost "cat - > backupfile.tar"
Tarballを作成し、それをSTDOUT
の通常のものに書き込みます。 sshを使用してリモートコマンドを実行しているため、STDINはSTDIN
のcat
にマップされます。これをファイルにリダイレクトします。
ネットワーク上のセキュリティについて心配する必要がない場合にホスト間でデータをパイプする便利な方法は、接続の両端でnetcat
を使用することです。
これにより、非同期で設定することもできます。
「レシーバー」(実際には、双方向通信がありますが、次のように考える方が簡単です)で、以下を実行します。
nc -l -p 5000 > /path/to/backupfile.tar
そして、「送信者」で実行します:
tar cf - /path/to/dir | nc 1.2.3.4 5000
要塞サーバー を使用する必要がある場合、状況は少しだけ複雑になります。
次のように、ssh
をコマンドとしてssh
に渡すことができます。
cat local_script.sh | ssh -A usera@bastion ssh -A userb@privateserver "cat > remote_copy_of_local_script.sh; bash remote_copy_of_local_script.sh"
疑似端末に注意
ここで重要なポイントは、ssh
はほとんどのツールと同様に、デフォルトでstdout
とstdin
を正しく処理するだけであることに注意してください。
ただし、Disable pseudo-terminal allocation.
やForce pseudo-terminal allocation.
などのオプションが表示され始めたら、少し試行錯誤する必要があるかもしれません。ただし、一般的なルールとして、文字化け/バイナリのジャンクを修正しようとしない限り、tty
の動作を変更したくない端末エミュレーター(人間が入力するもの)。
たとえば、ワークステーションのssh-agentが転送されるように-At
を使用する傾向があり、リモートでtmuxを実行しても、バイナリー(ssh -At bastion.internal tmux -L bruno attach
のように)が実行されません。そして、Dockerについても同様です(Sudo docker exec -it jenkins bash
など)。
ただし、これら2つの-t
フラグを使用すると、次のようなことを行おうとすると、データの破損を追跡するのが困難になります。
# copy /etc/init from jenkins to /tmp/init in testjenkins running as a container
ssh -A bastion.internal \
ssh -A jenkins.internal \
Sudo tar cf - -C /etc init | \
Sudo docker exec -i testjenkins \
bash -c 'tar xvf - -C /tmp'
# note trailing slashes to make this oneliner more readable.
1つのコマンドだけで、ssh公開鍵を別のホストに配置してみてください
ssh [email protected] 'cat >> .ssh/authorized_keys' < .ssh/id_rsa.pub
次のようにコマンドを実行しているユーザーのサーバー間でパスワードハンドシェイクを設定しないと、これが最も簡単です。
非圧縮
tar cf - . | ssh servername "cd /path-to-dir && tar xf -"
その場での圧縮
tar czf - . | ssh servername "cd /path-to-dir && tar xzf -"