Bashの完全またはcompgen -C(コマンド)オプションを使用する方法は?

Bashの完全またはcompgen -C(コマンド)オプションを使用する方法は?

このオプションは、bashでシェル補完を作成するときに-C非常に強力で一般的に見えます。これは次のように定義されます。

-氏 注文する

注文する サブシェル環境で実行すると、その出力は可能な完成として使用されます。

これは本当に簡単だと思います。しかし、奇妙なことではありません。私がするなら:

$ complete -C "echo one two three" test.sh

その後、[tab]を一度入力しtest.shてクリックすると、行が埋められます。

$ test.sh one two three test.sh  test.sh

退いてください。何? !比較しようと、

$ complete -W "one two three" test.sh

私が期待していたものとまったく一致しています。一つサムまたは二つできるだけ書いてください(もちろん並べ替えられた順序で)。

どこでも良い文書が見つからないので試してみてください。セミコロンが役に立ちますか?complete -C "echo one two three;" test.sh...ああ、わかりました、役に立ちました。一部test.sh、最後の奇妙な部分を削除するためです。しかし、まだ完全な文字列を埋めますone two three。上記の説明が「可能な完成」、複数形で間違いなく出ているので、これは奇妙です。 ...では、まあ、ああ、改行文字は?やってみようcomplete -C "echo -e 'one\ntwo\nthree';" test.sh

そうですね、希望はあります。これを入力するとtest.sh [tab]戻ってきますone three two。しかし、状況が間違っています。oあいまいさを解決するために1つを追加するのでtest.sh o[tab]それ返品

o      one    three  two

これは謎です。実際、私が入力したすべての文字列がリストに追加されます。これにより応答がtest.sh wtf[tab]届きます。one three two wtf何か複雑なことをしなければならないようだと思ったがcompgen、やはり予想通りだ-W。そして事実

$ complete -W '$(echo one two three)' test.sh

echoうまくいきます(変更可能な結果を​​生成できるよりも複雑な作業を行う場合は、早期の拡張/実行を防ぐために単一引用符に注意してください)。

私がここで何を見逃しているのでしょうか?

ベストアンサー1

このコマンドの役割は、-C完了要求に応答して挿入するテキストを決定することです。インターフェイスが少し奇妙です。

  • 引数は-Cbash スクリプトの断片として解釈されます。 Bashは、このコードスニペットに正しく引用された3つの文字列を追加します。

    • 引数が完了するコマンドです。
    • カーソルが位置する単語のプレフィックス(カーソルまで)。
    • カーソルの前の単語です。
  • 一部の変数が環境に追加されます。

    • COMP_LINE実行が完了した行全体を含みます。
    • COMP_POINTこれにはカーソル位置COMP_LINE(0から計算)が含まれます。
    • COMP_TYPE正常完成は9番、曖昧な完成の代替リストは33番、メニュー完成は37番、曖昧な完成間の切り替えは63番、部分完了後、リスト完了は64番だ。
    • COMP_KEY完了をトリガーしたキーが含まれます(たとえば、ユーザーが押された場合はtab Tab)。
  • コマンドの出力は、現在の単語を置き換えるテキストとして解釈されます。これは追加されたサフィックスではなく代替サフィックスです。コマンドは、指定されたプレフィックスに基づいてフィルタリングする必要があります。これには複数の行を含めることができます。この場合、各行は可能な代替行と見なされます。

これは提供されたメカニズムとほぼ同じですが、より良いです。録音された、がある関数の場合-F。関数のインターフェースがよりきれいになりました。現在のコマンドの単語リストを読むことができます。COMP_WORDS変数と現在の単語の開始位置COMP_CWORD;彼らは結果を次のように書く。COMPREPLY大量に。

便利な引数(特に完成するプレフィックス)がコマンドの最後に渡されるため、これは-Cほとんど外部コマンドでのみ使用できます。もちろん同様のものを使用することもできますが、sh -c …きれいではありません。

complete -C 'sh -c '\'for x in one two three; do case $x in "$1"*) echo "$x";; esac''\'

おすすめ記事