stdin
文字列を収集し、完了したら再接続するプログラムが欲しいとします。
次のトリックを使用すると、これを実行できることがわかります。
(echo id; cat) | sh
良い結果。stdin
使用中なので閉じませんcat
。しかし、出力は汚れています。
もっと深く掘り下げると、それが欠けていることがわかりましたtty
。
私の理解が正確であれば、sh
パイプラインに穴がないことですtty
。
私が見つけた秘訣はexpect
。
ただファイルに入れてください:
spawn sh
reattach
その後、cat
コントロールを回復したら、次のようにします。
expect exp.sh
tty
これは私が必要なすべてを行うことができるので良いです:ssh
、tmux
など...
私がなぜそれを理解していない唯一のことは、私が入力したすべてのものを端末で見直すことができるということです。
例:
(echo whoami; cat) | sh
moon
expect exp.sh
spawn sh
sh-3.2$ whoami
whoami
moon
whoami
ログインする前に、出力の最後の行をメモしてください。
誰かが私に理由を説明できますか?それは直接接続されているので、明らかにstdout
fromの属性ではありません。はい、愚かな場合でも、以下を試しました。それから何も起こりませんでした。cat
sh
(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行編集機能を使用することもできます。
ユーザーが対話型シェルを使用する前にコマンドを自動的に実行するための追加オプションについては、以下を参照してください。