私はbashスクリプトの出力をbashスクリプトを呼び出す行にリダイレクトする方法を見つけることができるかどうかを調べるために2時間のほとんどを費やしました。
私が探しているものを説明するために使用できる最良の例は、[TAB]を押したときに実行される完成関数です。
$ech[tab] #--> $echo
#-->
「echo」という単語を完成する方法を示す必要があることを指摘する必要があります。
私が見つけることができる最も近い方法は、いくつかのオプションを「エコー」に設定して\b\b
読み取ることができ、stdoutが同じ行を更新できるようにすることです。しかし、それは私が探しているものではありません。コンソール入力から現在のラインまたは次のラインに直接出力できるようにしたいと思います。 bashスクリプトでも可能ですか?
編集する:
答えてくれた皆さんに感謝します。元の質問を更新し、質問のタイトル自体も変更する必要があるようです。
私の質問の範囲は次のように変更されました。もはやスクリプトだけで何が達成でき、何が達成できないのかという質問ではありません。私の最初の目標は、完成した「機能」をシミュレートすることであり、徐々にこれが実際には組み込み bash コマンド。
(bashのタブ補完コマンドのエミュレーションを開始するために)私が知っておくべき特定のライブラリは次のとおりです。リーディングライン図書館。 bashの完成自体はC(++?)で実装されています。
とにかく、あなたの洞察力のある回答にもう一度感謝し、上記の記事に記載されている他のヒントがある場合(おそらくReadlineまたはCompletionライブラリを個人的に使用して得られた情報かもしれません)、あなたのコメントを読むことを期待してください。します。
答え1
私はこの問題を2つの方法で解釈できます。すでに端末に書かれているものを他のもので上書きしたい(簡単に行われた)または現在の対話型シェル入力をプログラムで提供したいようです。
問題は、これらの質問が最終的に非常に異なる2つを意味することです。多くの人が犯す間違い(どうせ一つ作ったけど - 繰り返し)これは、端末画面に印刷された視覚文字をキーボードで入力した入力と同じにすることです。しかし、現実は、キーボードが画面の出力よりも操作しやすいということです。前者を後者に変換するには、2つの間で行う必要があることがたくさんあります。端末から印刷するのは便利ですが、しばしば嘘をつきます。
シェルに入力を提供したい場合は、画面に書き込むことが役に立ちません。もちろんこれを行うこともできます。ターミナルライン上を移動するために標準のVT102+エスケープシーケンスを実行することは次のとおりです。
printf '\033[A'
...しかし、これを行うと、あまり起こらないようです。シェルがこれを読んでいないからです。書くあなたと同じ場所に行きます。あなたはできます:
printf '\033[A'; cat
...実際にそれが何をするか見てください。cat
これにより、シェルがすぐに新しいプロンプトを描画するのを防ぎます。あなたはできます(おそらく)[
角かっことA
複数行の間に数値パラメータを追加します。下にB
、左にD
、右に行くことができますC
。検索可能なシーケンスとともに、tput
呼び出しの結果を名前付き変数に保存するのは通常、人々が行う方法であり、実際にはそうです。ターミナルは興味深いものです。termcap
man termcap
本当に楽しい時間を過ごしたい場合は、以下を試してください。
stty raw isig -echoctl; cat >/dev/null
xterm
互換性のある端末エミュレータで(stty
サポートが提供されていますが、-echoctl
そうでない場合は必要ありません。)デフォルトでは、矢印キーを使用して端末画面の周りを移動してテキストを入力できる必要があります。しかし、それらのどれも重要ではありません。なぜなら、ディスプレイをオーバーライドしているからです。シェルはそれについて全く気にしません。
シェルに影響を与えたい場合は、シェルの標準入力と話す必要があります。インタラクティブシェルは、一般的に呼び出されたときにあらかじめ知らせない限り、これに関してユーザーが話していることをあまり聞きません。それ以外の場合は、キーボードの音だけを聞きます。それがまさにキーボードの音です。(より正確に言えば、キーボードは標準入力です。)。しかし、あなたには選択の余地があります。
インタラクティブなシェル入力スクリプトを書く良い方法は、それを遅らせることです。たとえば、デフォルトでは何もせずにキーボード入力を受け入れ、次の内容をエコーするダミープロンプトを取得できますstderr
。
sh -niv 2>&1 >/dev/null | ...
それはあなたのものである必要はありません/bin/sh
。それはうまくいきますbash
。すべての一般的なタスク(コマンド履歴を含む)をbash
実行しますが、特定のタスクを実行し、すべての入力をパイプに詳細に印刷します。その後、任意の方法で方向を指定できます。いくつかのフィルタリングを経た後、他のパイプを介して別のパイプに接続することもできます。readline
$PS1
-n
-v
bash
こんなことはたくさんできますが、過去に戻ることはできません。スクリプトの開始後、最後のコマンドが終了しました。変更することはできませんが、将来のコマンドをフィルタリングするように並べ替えることができます。