Bashは独自の入力ストリームに書き込むことができますか?

Bashは独自の入力ストリームに書き込むことができますか?

交流は可能ですか?強く打つシェルは、ユーザーがそのプロンプトでそのテキストを入力したかのように、次のコマンドプロンプトに表示されるようにいくつかのテキストを出力するコマンドを入力しますか?

sourceスクリプトがコマンドラインを生成し、スクリプトが終了した後にプロンプ​​トが返されたときに表示されるように出力して、ユーザーがenter実行する前に編集を選択できるようにしたいと思います。

これは次の方法で達成できますが、xdotool端末がXウィンドウにあり、インストールされている場合にのみ可能です。

[me@mybox] 100 $ xdotool type "ls -l"
[me@mybox] 101 $ ls -l  <--- cursor appears here!

bashだけを使ってこれは可能ですか?

ベストアンサー1

を使用すると、次のプロンプトのために行エディタバッファにいくつかのテキストを配置zshできます。print -z

print -z echo test

echo test次のプロンプトで編集するために使用できるラインエディタが起動します。

同様の機能がないと思いますbashが、多くのシステムで次のターミナルデバイス入力バッファを埋めることができますTIOCSTI ioctl()

perl -e 'require "sys/ioctl.ph"; ioctl(STDIN, &TIOCSTI, $_)
  for split "", join " ", @ARGV' echo test

echo test端末から受信したように、端末装置の入力バッファに挿入されます。

よりポータブルなバリエーション@mikeのTerminologyやり方query status reportそして、セキュリティを犠牲にすることなく、かなり標準的なエスケープシーケンスをターミナルエミュレータに送信することです。<ESC>[5n端末は常に入力として応答し<ESC>[0n、挿入したい文字列にバインドします。

bind '"\e[0n": "echo test"'; printf '\e[5n'

GNUの内部では、screen次のこともできます。

screen -X stuff 'echo test'

これで、TIOCSTI ioctlメソッドに加えて、端末エミュレータに入力したかのようにいくつかの文字列を送信するように要求します。この文字列は、ターミナルローカルエコーが無効になる前に表示される場合に表示されますreadline(ラインエディタで)。bashいいえシェルプロンプトでディスプレイが少し混乱します。

この問題を解決するには、readlineがエコーを無効にしたときに応答が到着するように端末への要求の送信を少し遅らせることができます。

bind '"\e[0n": "echo test"'; ((sleep 0.05;  printf '\e[5n') &)

(これはsleep1秒未満の解像度をサポートすると仮定します。)

理想的には、次のようなことをしたいと思います。

bind '"\e[0n": "echo test"'
stty -echo
printf '\e[5n'
wait-until-the-response-arrives
stty echo

しかし、bash(そして逆にzshwait-until-the-response-arrives応答を読まないことはサポートされていません。

has-the-response-arrived-yetただし、次の特徴がありますread -t0

bind '"\e[0n": "echo test"'
saved_settings=$(stty -g)
stty -echo -icanon min 1 time 0
printf '\e[5n'
until read -t0; do
  sleep 0.02
done
stty "$saved_settings"

追加読書

バラより@starfryの返信これは@mikeservと私自身が提供した2つのソリューションを拡張し、より詳細な情報を提供します。

おすすめ記事