プログラムをstdinに再接続する

プログラムをstdinに再接続する

stdin文字列を収集し、完了したら再接続するプログラムが欲しいとします。

次のトリックを使用すると、これを実行できることがわかります。

(echo id; cat) | sh

良い結果。stdin使用中なので閉じませんcat。しかし、出力は汚れています。

もっと深く掘り下げると、それが欠けていることがわかりましたtty

私の理解が正確であれば、shパイプラインに穴がないことですtty

私が見つけた秘訣はexpect

ただファイルに入れてください:

spawn sh
reattach

その後、catコントロールを回復したら、次のようにします。

expect exp.sh

ttyこれは私が必要なすべてを行うことができるので良いです:sshtmuxなど...

私がなぜそれを理解していない唯一のことは、私が入力したすべてのものを端末で見直すことができるということです。

例:

(echo whoami; cat) | sh
moon
expect exp.sh
spawn sh
sh-3.2$ whoami
whoami
moon

whoamiログインする前に、出力の最後の行をメモしてください。

誰かが私に理由を説明できますか?それは直接接続されているので、明らかにstdoutfromの属性ではありません。はい、愚かな場合でも、以下を試しました。それから何も起こりませんでした。catsh(echo id; cat > /dev/null) | sh

その後、キーボードで入力した内容は表示されませんtty/プロパティ?pty

ベストアンサー1

{ echo 'exec <&3 3<&-; id' | sh -si; } 3<&0

ほとんどの実装で動作するようですsh。対話型シェルに要求し-i(そうでなければ、一部のシェルはターミナルデバイスではないためstdinを無効にします)、シェルのstdinをパイプで開始し、以前に記述子にexec <&3.stdinとして保存された元の(外部)ファイルに変更するように指示します。します。サム3<&0

我々はこれを行う今後実行中ですが、idまだ同じコマンドを使用しています。ワイヤー、標準入力idも復元されます。標準入力を読み取らないので重要ではありませんが、エディタやidシェルなどの対話型コマンドになります。

あなたが入力した内容を私が見たのはなぜですか(echo id | cat) | sh?あなたの実装はsh非常に古いバージョンであり、bashインタラクティブモードで実行されているようです。-i使用したのと同じようにプロンプ​​トが表示されます。

その後、独自のラインエディタを実装しますが、ttyデバイスの独自のラインエディタを無効にする方法はありません(標準入力がttyデバイスではなくパイプであるため)。したがって、ttyデバイスを介して入力した内容のエコーが得られます。行ルールが表示され、Enterキーを押すとすぐに、パイプですぐに作成された末尾のcat改行文字を含む行バッファのすべての内容がすぐに表示され、bash独自の行エディタの一部としてbash出力されます。echo

あなたがそうするなら、私は疑います:

stty -icanon -echo; (echo id; cat) | sh; stty sane

bashより良い動作を得ることができ、入力したすべての文字を直接受信するので、readline行編集機能を使用することもできます。

ユーザーが対話型シェルを使用する前にコマンドを自動的に実行するための追加オプションについては、以下を参照してください。

おすすめ記事