12

1 つの引数 ("encrypt" または "decrypt") とファイルのリストを受け取る "foo" という名前のコマンドがあるとします。最初の引数を支援し、他の引数の標準ファイル補完を有効にする bash 補完スクリプトを作成したいと考えています。私が来ることができた最も近いものはこれです:

complete -F _foo foo

function _foo()
{
    local cmds cur
    if [ $COMP_CWORD -eq 1 ]
    then
        cur="${COMP_WORDS[1]}"
        cmds=("encrypt decrypt")
        COMPREPLY=($(compgen -W "${cmds}" -- ${cur}) )
    else
        COMPREPLY=($(compgen -f ${COMP_WORDS[${COMP_CWORD}]} ) )
    fi
}

これにより、最初の引数が正しく実行され、後続の引数のために現在のディレクトリからファイル名が選択されます。しかし、現在のディレクトリに、ファイル baz.txt を含むサブディレクトリ bar が含まれているとします。ba-TAB-TAB を入力した後、補完は "bar " ("r" の後のスペース) になり、次の引数を選択する準備が整います。私が欲しいのは、結果が「bar /」(スラッシュの後にスペースがない)である標準のbash補完であり、サブディレクトリ内のファイルを選択する準備ができています。それを取得する方法はありますか?

4

2 に答える 2

13

bash のドキュメントは少し謎めいている場合があります。最も簡単な解決策は、補完関数バインディングを変更することです。

complete -o filenames -F _foo foo

これは、関数がファイル名 (ディレクトリを含む) を返し、結果の特別な処理が有効になっていることを意味します。

COMPREPLY[](IMHOドキュメントでは、これが補完機能によって設定されたように効果的に後処理されること、および-o適用されたときに含まれるオプションの一部が効果がないようにcompgen見えることを明確にしていません。)

以下を使用して、通常の bash の動作に近づけることができます。

 complete -o filenames -o bashdefault -F _foo foo

これにより、「〜」完了が返されます。

ただし、上記には2つの問題があります。

  • 「encrypt」または「decrypt」という名前のディレクトリがある場合、キーワードの展開により末尾の「/」が成長します
  • $VARIABLE展開は機能せず$\$ファイル名と$. 同様に @host、展開は機能しません。

これに対処するために私が見つけた唯一の方法は、compgen出力を処理することであり、「ファイル名」の後処理に依存しないことです。

_foo()
{
    local cmds cur ff
    if (($COMP_CWORD == 1))
    then
        cur="${COMP_WORDS[1]}"
        cmds="encrypt decrypt"
        COMPREPLY=($(compgen -W "$cmds" -- "$cur"))
        COMPREPLY=( "${COMPREPLY[@]/%/ }" )   # add trailing space to each
    else
        # get all matching files and directories
        COMPREPLY=($(compgen -f  -- "${COMP_WORDS[$COMP_CWORD]}"))

        for ((ff=0; ff<${#COMPREPLY[@]}; ff++)); do
            [[ -d ${COMPREPLY[$ff]} ]] && COMPREPLY[$ff]+='/'
            [[ -f ${COMPREPLY[$ff]} ]] && COMPREPLY[$ff]+=' '
        done
    fi
}

complete -o bashdefault -o default -o nospace -F _foo foo

cmd(上記の不要な配列も削除し、compgenより堅牢にして、ファイル名のスペースまたは先頭のダッシュを処理します。)

欠点は、中間補完リストを取得したとき (つまり、複数の一致を表示するために 2 回ヒットしたとき)、ディレクトリのtab末尾に / が表示されないことです。受け付けます。nospace~ $ @

要するに、独自の補完と完全な bash 補完動作を自明に組み合わせることはできないと思います。

于 2013-01-25T14:55:07.947 に答える