web-dev-qa-db-ja.com

compgen警告:-Cオプションが期待どおりに機能しない

compgen -Cオプションを使用する正しい方法は何ですか?

Bashのプログラム可能な完了、特にcompgen組み込み関数について学習しようとしています。さまざまなcompgenコマンドラインオプションを試していますが、-Cフラグがどのように機能するのかわかりません。 GNU Bashリファレンスマニュアル から:

-Cコマンド

コマンドはサブシェル環境で実行され、その出力が可能な補完として使用されます。

これに基づいて、私は次のようなものが機能することを期待しています:

$ compgen -C 'echo "first_option second_option"' f
first_option

しかし、代わりに、私はこれを取得します:

$ compgen -C 'echo "first_option second_option"' f
-bash: compgen: warning: -C option may not work as you expect
first_option second_option  f

OS X 10.7のBashバージョン4.2.45とUbuntu12.04のBashバージョン4.2.25でこれを試しましたが、どちらの場合も同じエラーが発生します。

-bash: compgen: warning: -C option may not work as you expect
4

Bashのマニュアルページを再度参照してください。

-Fまたは-Cオプションを使用する場合、プログラム可能な完了機能によって設定されたさまざまなシェル変数は、使用可能ではありますが、有用な値を持ちません。

これが言及している「予期しない動作」だと思います。 compgenによって作成されたサブシェルに_$COMP_WORDS_と_$COMP_CWORD_がないということは、最初の「f」が結果をフィルタリングするために渡されないことを意味します。したがって、最初の2つのオプションが表示されます。 3番目の「f」-に進みます。

この出力を抑制する方法がないように見えることは、一見するとさらに予想外です(stderrをパイプすることを除いて)-しかし、実際には合理的な説明があります。引数は、completeコマンドに対して使用することを目的としています。このコマンドを使用すると、compgenはコードと引数を共有し、より意味があります。

completeコマンドは、完了コマンドの登録に使用されます。

_complete -C /tmp/test.sh mycmd_

そして、bash sourcepcompletiongen_command_matches()またはその周辺)は、「f」がどのように結果に含まれるかを説明しています。

_/* [...]
 $0 == cs->command         (command to execute for completion list)
 $1 == command name        (command being completed)
 $2 = Word to be completed (possibly null)
 $3 = previous Word
 [...] */
_

例の3番目の結果は、もちろん、コマンド入力が引数_$2_として返されることです。上で作成した補完仕様を使用すると、引数に注釈を付けるスクリプトでどのように使用されるかをより明確に示すことができます。

_ $ cat > /tmp/test.sh << EOF
 x=0
 for arg in $0 $@; do⋅
   echo "$x:$arg"; x=$[$x+1]
 done
 EOF
_

その後:

_ $ complete -C /tmp/test.sh mycmd
 $ mycmd prevarg curarg<tab><tab>
 0:/tmp/test.sh   1:mycmd   2:curarg   3:prevarg
_

したがって、_-C_がcompgenで使用できないと言っているわけではありません。 $()を使用するよりも良い方法はありません。

残りの質問は、「なぜ-Cと-Fがcompgenに対して定義されているのか」ということだと思います。知りません。簡単かもしれません。あるいは、おそらく作者は、有用な機能を単に無効にするよりも、(かなりあいまいな)警告の方が良いと判断したのかもしれません。答え、そしておそらくこの時点で行うべき正しいことは、 バグレポート 著者からの説明や改善されたドキュメントを求めることです...

2
gra