Debianファイルの完成ごみ$_を修正する方法はありますか?

Debianファイルの完成ごみ$_を修正する方法はありますか?

私はSlackware Linuxについて長年の経験を持っていますが、この問題を見たことはありません。私は最近Debianサーバーを管理していますが、これが迷惑になりました。

私はしばしば、以前に入力したコマンドの最後の引数を繰り返すためにbashコマンドで "$_"を使用します。時々、次のような動作が表示されます。

dschrag@mo:~/dev/dancer$ ls -l アプリ/db/schema/
合計12個
-rw-r--r-- 1 dschrag dschrag 268 5月19日 10:51 gau_account.sql
-rw-r--r-- 1 dschrag dschrag 558 5月19日、13:02 gau_import.sql
-rw-r--r-- 1 dschrag dschrag 270 5月19日 13:09 gau_source.sql
dschrag@mo:~/dev/dancer$ cd $_
-bash: cd: _filedir: そのファイルやディレクトリはありません。
dschrag@mo:~/dev/dancer$

周りを見回すと_filedirで使われたものでした/usr/share/bash-completion/bash_completion

私はファイル補完機能を何も考えずに使用しているので、この欠陥が発生したときに何をしていたのかを理解するのは困難です。この問題を調査するのに苦労した人はいますか?

答え1

プログラム可能な完了(「bash完了」)を有効にしました。これはソース/etc/bash_completionまたはbashrcのどこかで/usr/share/bash-completion/bash_completion行われます。たとえば、jessieのbashrcスケルトンでは、次のようになります。

# enable programmable completion features (you don't need to enable
# this, if it's already enabled in /etc/bash.bashrc and /etc/profile
# sources /etc/bash.bashrc).
if ! shopt -oq posix; then
  if [ -f /usr/share/bash-completion/bash_completion ]; then
    . /usr/share/bash-completion/bash_completion
  elif [ -f /etc/bash_completion ]; then
    . /etc/bash_completion
  fi
fi

完了する作業の1つはマルチングです$_。クイック修正はbashの完成をロードしないことです。

complete-filename別の回避策は、この関数の代わりにこの関数を使用してファイル名の完成を完了することですcomplete。これは代わりにESC/またはAlt+ /(端末の設定に応じて)を押すことを意味しますTabbindを使用または編集して、これらのキーがバインドされているキーを変更できます~/.inputrc

また、bashの完成に関するバグレポートを提出したいと思います。

答え2

単純追跡

cdまず、bashコマンドの補完を使用するときに実際に何が起こるのかを知ることができます。

$ complete -p | grep cd
complete -F _filedir_xspec cdiff
complete -o nospace -F _cdrecord wodim
complete -o nospace -F _cdrecord cdrecord
complete -o nospace -F _cd cd

_cd完了を使用すると、関数が呼び出されるのを見ることができますcd。したがって、_cd関数内で$_変数値が変更された問題が発生したことがわかります。

機能を確認してください_cd:(私のUbuntu 12.04.4では/etc/bash_completion

# This meta-cd function observes the CDPATH variable, so that cd additionally
# completes on directories under those specified in CDPATH.
#
_cd()
{
    local cur IFS=$'\n' i j k
    _get_comp_words_by_ref cur

    # try to allow variable completion
    if [[ "$cur" == ?(\\)\$* ]]; then
        COMPREPLY=( $( compgen -v -P '$' -- "${cur#?(\\)$}" ) )
        return 0
    fi
    ....
        _filedir -d

    if [[ ${#COMPREPLY[@]} -eq 1 ]]; then
        i=${COMPREPLY[0]}
        if [[ "$i" == "$cur" && $i != "*/" ]]; then
            COMPREPLY[0]="${i}/"
        fi
    fi

    return 0
}

$_それはあなたが古い自我を失うようにする多くのことをします。おそらく配線に問題があるようです_filedir -d。 (私のテストでは$_に変更されました-d。)

必要な内容を失わないようにするには、関数に入るとすぐにその値を保存し、終了する$_前に_cd復元できます。$__cd

_cd()
{
    local __=$_

    ....

    : $__
    return 0
}

ここで重要なのは、:で何もせず、パラメータ(必要な値)があるため、bash関数を入力する前に以前の値に設定されることです。$__$_$__cd

結論として

bash completion変数を無駄にしないことは非常に難しいです$_。上記の例では、を使用します。cd他の機能bash_completionと以下のすべてのファイルについても/etc/bash_completion.d/同じことを行う必要があります。これは信頼できるソリューションではありません。

最後のコマンドラインの最後の引数を取得するには、以下を試してくださいbash history expansion

$ echo 1 2 3
1 2 3
$ echo !$
echo 3
3

関連情報