バッシュ完了-Cと-F

バッシュ完了-Cと-F

Bash完了設定で(https://github.com/scop/bash-completioncomplete -F)私のシステムが提供しますが、これは完全対相手に対する明確な好みを持っているようですcomplete -C

complete -p | grep -- -C # no match

-F2つの違いは、get form関数には変数から入力を読み込んで変数に出力する関数が必要ですが、-Cget formコマンドは位置引数から入力を読み取って出力する関数が必要なようですstdout

私は2番目のアプローチがより実用的で、完成した関数/プログラムをデバッグするのがより簡単であることを好みます(特定の変数コンテキストに依存しないため)。

しかし、https://github.com/scop/bash-completion前者を好む点が気になります。-C新しいプロセスの明白なパフォーマンスオーバーヘッド(IMHO UIでは無視できます)に加えて、このアプローチに欠点はありますか?

答え1

complete -C {command}後者は実際に機能が必要なので、なぜ「より実用的な」ことを考えるのかはわかりませんcomplete -F {function}。したがって、あなたが好む理由は不明です。しかし、あなたは正しいです。ほとんどすべての例とドキュメントは、たとえば、complete ... -F {function} ...このcomplete -F _foobar foobar関数が_foobar仮想コマンドの完成オプションを生成するために使用されますfoobar

主な理由は次のように推測されます。

  • " "関数は_foobar複数のコマンドを完了するために使用できます。たとえば、パッケージには、foobar完了したコマンドの名前を知るために関数に渡されるfooコマンドがbarあるかもしれません。$1
  • 関数バリアントは、完成を実行するためのより多くの情報を提供するようです。-C""バリアントは比較するともっと愚かに見えます(しかし、私は-Fいつも「」バリアントを使用します。)
  • コマンドの出力に依存するよりも関数(COMPREPLY配列変数を介して)を介して完了オプションを設定する方が簡単であるため、コマンドは子プロセスで実行されるため、情報を渡してインポートするのは困難です。
  • 「-Cコマンド」バリアントは子プロセスを作成し、「tab-tab-tab」を押すと瞬間的な感触を与えたいときに追加の遅延を生成します。
  • 「-Cコマンド」バリアントは、completeステートメントに長く複雑なコマンドを含めるか、外部シェルスクリプトを呼び出します。この場合、そのスクリプトの場所を送信して追跡する必要があります(これは痛みを伴うプロセスです)。

また、個人的には「完成」作業を通じて、bashの以前のバージョンとさまざまなUnix(AIX、HP-UX、Solaris、Linux、BSD)で作業する必要があり、それをサポートするさまざまな項目を発見しました。作業時に " complete"が返されるので、true次のイディオムを使用してください。これはbashバージョン間でより移植性があるようです(-F {function} {commmand}""の使用法がその "" / Cleanerよりも単純であることを示すため、ここにのみ含まれています-C "command")。

complete -o bashdefault -o default -o nospace -F _cmd cmd 2>/dev/null \
|| complete             -o default -o nospace -F _cmd cmd 2>/dev/null \
|| complete             -o default            -F _cmd cmd 2>/dev/null \
|| complete                                   -F _cmd cmd

cmd1同様に、存在する場合はすべて本質的に同じ補完を使用します(たとえば、作成したホスト名のリストを使用するための完成スクリプトをcmd2考慮)。cmd3scpssh

for c in cmd1 cmd2 cmd3; do
    # or that long complete statement shown above
    complete -o bashdefault -o default -o nospace -F _cmd $c 2>/dev/null
done

参考までに:

関連情報