これらは異なって働きます:
$ seq 1000000 | (ssh localhost sleep 1; wc -l)
675173
$ seq 1000000 | (ssh localhost sleep 1 </dev/null; wc -l)
1000000
stdinを読む理由は何ですかssh
?
答え1
-n
sshは、オプション(またはoptions)を使用して読み取らないように指示しない限り、常に標準入力を読み込みます-f
。
その理由は、次のようなことができるからです。
tar cf - somedir | ssh otherhost "tar xf -"
sshはリモートコマンドが入力を許可するかどうかを知らないため、常にこれを行います。
おそらく最初のコマンドで起こることができるのは、seqがネットワークとパイプバッファ(seq - > ssh - > sleep)を埋め、sleepは何も読み取らないため、より多くの読み込みを待ってブロックされ、次にsleepが終了してこの問題が発生するということですです。バッファ全体をダンプした後、seqはブロック解除され、残りはwcに送信されます。
次のような結果が得られます。seq 1000000 | ( cat | cat | sleep 1; wc -l)
2番目のコマンドではまだstdinを読み込んでいますが、外部で/ dev / nullをstdinに割り当てました。
答え2
Unixの入出力は単方向通信の基本要素に基づいています。write
データをプッシュするには1を使用し、read
データをインポートするには1を使用し、データの可用性を照会するには1を使用しますselect
。データ消費者が「データをお願いします」という要求を送信し、生産者がデータで応答したり、消費者が「どのくらい多くのデータを与えることができますか?」という要求を送信するウェブの一般的なモデルとは異なります。プロデューサはサイズで応答しますread
。消費者はデータが利用可能であることを確認するために呼び出しを行うことができます。select
これは生産者とはまったく関係ありません。
SSHサーバーは、サーバー上で実行されているアプリケーションが標準入力から読み取りを積極的に試みるかどうかを知ることができます。 SSHサーバーは、select
データの書き込みがブロックされていることを確認するために呼び出すことができます。ただし、アプリケーションが断続的に読み取ろうとすると、SSHサーバーがselect
正確なタイミングで呼び出されないため、アプリケーションがデータを読み取ろうとしている状況が見逃される可能性があります。そして、SSHサーバーは、アプリケーションが標準入力でデータを使用できるように要求するために呼び出しを行うかどうかを知る方法がありませんselect
。 SSHサーバーが必要なときにアプリケーションにデータを提供する唯一の方法は、データが利用可能になったときにアプリケーションにデータを提供することです。
これを行うには、クライアントがサーバーにデータを送信する必要があります。したがって、クライアントは標準入力を読み取り、データが利用可能になるとすぐに渡します。
クライアントが標準入力から一部のデータを読み取った後、読み取った内容を取り消すことはできません。サーバー側アプリケーションが最終的にデータを消費しない場合、データは失われます。
したがって、呼び出し時にssh
SSH接続を介して標準入力をルーティングするかどうかをクライアント側で決定する必要があります。これはサーバーがあなたに話すことができるものではありません。
また、見ることができます同じシェルで複数の接続が開始された場合、バックグラウンドで実行されているSSH接続は終了しません。端末に関連する類似しているがより複雑なシナリオを見てください。
そして友達。