あるコマンドから別のコマンドにデータをパイプできます。例:
_$ echo test | cat
test
_
何を呼び出すべきかわからない 私が使用して同様の効果を得ることができる操作:
_$ cat < <(echo test)
test
_
ここで、<(echo test)
は、ファイルをその場で作成するためのバシズムです。通常のファイルを使用すると、次のようになります。
_$ cat file
test
$ cat < file
test
_
これはsshでも同様に機能します。
_$ ssh server cat < <(echo test)
test
_
Ssh-exampleをベースとして使用すると、次のようなことができると思うかもしれません。
_$ pdsh -a cat < <(echo test)
_
ただし、接続されたマシンのcatにデータは送信されず、コマンドは終了しません。
tee
は、stdinで受信したものを複数の場所に送信できるようです。
_$ tee >(cat) >(cat) < <(echo test)
test
test
test
_
pdsh
で同じことを達成することは可能ですか?
pdsh
開発者の1人と連絡を取り、次のことを学びました。
必要なのは「stdinbroadcast」ですが、残念ながらこれに対するサポートはpdshに追加されていません。これは素晴らしい機能ですが、歴史的にはそれほど必要ではなかったため、これまでに行われたことはありませんでした。
これは、この投稿ですでに確立されていることを確認しているようです。
ただし、その後に次のことが続きました。
ところで、stdinブロードキャストを実行することが不可能であるというわけではありません。 HPCスケジューラーの一部である並列ランチャーは、srun(1)などのようにそれを行うことができます。このメカニズムでは、stdinが一度読み込まれ、リモートプロセスごとにバッファにコピーされます。つまり、複製は並列ランチャーの内部で行われます。
フォローアップの理由は、 そのstackexchangeの投稿 にいくつかの誤解を招く答えがあるためです。
シリアルforループの問題を回避する別の方法は、GNU parallelまたはpdsh-Rexecからsshを実行することです。pdsh-Rexecの例:
$ pdsh -R exec -w Host [0-10] bash -c'ssh%h cat <<(エコーテスト) '
もちろん、ここでの欠点は、リダイレクト用の一時ファイルをN回作成していることです。出力をローカルファイルに入れてから、そのファイルを各sshコマンドにキャットする方がよい場合があります。
Forループに対するpdsh/parallelの利点は、並列処理が得られることです。
私自身のテストでは、その正確な例を機能させるのにいくつかの問題がありました。
root@master# pdsh -R exec -w Host1 bash -c 'ssh %h cat < <(echo test)'
Host1: bash: -c: line 0: syntax error near unexpected token `<'
Host1: bash: -c: line 0: `ssh n1 cat < <(echo test)'
pdsh@master: Host1: bash exited with exit code 1
1つの小さな微調整がそれを生かし、それは「通常の」ファイルを使用しています。
root@master# cat data.txt
test from file
root@master# pdsh -R exec -w Host1 bash -c 'ssh %h cat < data.txt'
Host1: test from file
結論:pdsh
は、私が求めていたものをより適切に処理する機能を拡張できますが、現在でも、私が求めていたものを実現する方法があります。
コマンド全体がリモートホストで実行されるように、リモートコマンドを引用する必要があります。例えば.
_pdsh -a 'cat < <(echo test)'
_
引用符がない場合、onlycat
はリモートホストで実行されます。リダイレクト(_<
_)および プロセス置換<(echo test)
はローカルホストで実行されます。
_echo test
_の出力を消費するリモートホストが1つしかない場合(たとえば、ssh
コマンドを使用)、これは機能します...しかし、その出力を消費したいリモートホストが複数ある場合(たとえば、pdsh
の代わりにssh
を使用したため) 、動作しません。
データを複数のコンピューターに送信したい理由は、データを一時ファイルに入れてリモートマシンに転送するのが簡単ではないためだと思います。出力が継続的に生成される場合もあれば、大きすぎてディスクに収まらない場合もあります。
GNUParallelの--tee
はあなたを助けることができます:
seq 1000 |
parallel --tee --pipe ssh {} wc ::: server1 server2
seq 1000
とwc
をコマンドに置き換えます。
変更されていないGNU/Linuxシステムでは、これは250台のサーバーで実行できるはずです。さらに必要な場合は、ファイルハンドルが不足し、ulimit -n
または/etc/security/limits.conf
の/proc/sys/fs/file-max
またはnofile
を変更する必要があります。
舞台裏では次のことが始まります(GNU Parallelはコマンドからstdoutとstderrを収集しますが、原則は同じであるため、少し複雑です):
... | tee >(ssh server1 wc) >(ssh server2 wc) >/dev/null
したがって、パフォーマンスはtee
に匹敵します。ただし、一度に数台だけでなく、すべてのサーバーに並列にssh
が存在することも意味します。