bash 完了時に下線変数 $_ が変更されないようにする

bash 完了時に下線変数 $_ が変更されないようにする

Bashでタブ補完を使用すると、$_変数が変更されます。

$ mkdir test
$ cd <TAB><TAB> $_
bash: cd: -d: invalid option
cd: usage: cd [-L|[-P [-e]]] [dir]

<TAB><TAB>現在のディレクトリ内のすべてのファイルが一覧表示されますが、出力を使用して書き込まれるわけではありません。$_この行で実行されるコマンドはですcd $_。)

予想される動作は次のとおりです./test

Bashが変更を完了しないようにする方法は$_

答え1

あなたは使用していますbash-completionパッケージ(または派生物)。コマンドの各パラメータに対して完了しますcd(出力に表示されますcomplete -p)。

complete -o nospace -F _cd cd

_cd完了するかどうかを確認するには、この関数を呼び出します(簡潔さのために少し編集されています)。

_cd()
{
    local cur prev words cword
    _init_completion || return

    local IFS=$'\n' i j k

    compopt -o filenames

    if [[ -z "${CDPATH:-}" || "$cur" == ?(.)?(.)/* ]]; then
        _filedir -d
        return 0
    fi
    ....

たとえば、CDPATH設定されていないディレクトリを完了すると、コマンドの最後に確認された引数は-d自動的に配置されます_。この関数には、同様の副作用を持つ他のいくつかのコードパスがあります。

bashの内部にあるため、_伝統的な保存/復元(例:IFS)必要に応じて機能しません。あなたできるこれを行うには、いくつかのトリックを使用してください。

_cd()
{
    local save_="$_"
    ...
    : $save_
    return 0

_関数に入るとすぐに保存する必要があります。:このコマンドはそれ自体は何もしませんが、設定などのコマンドの一般的な副作用がある空のコマンドです_。この回復操作は、潜在的に破壊的な機能のすべての戻りポイントに必要です。ここにも微妙さがあります。通常、_関数が返された直後(予想どおり関数呼び出しの最後の引数)に設定され、メソッドは無効になります。ただし、完成関数を呼び出すと明示的に呼び出されないため、これは発生しません。あまり強力な力ではないようですが…

(私は好む歴史的拡張!$そして、この問題が発生しないことに固執してください。 )

関連情報