私は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+ /(端末の設定に応じて)を押すことを意味しますTab。bind
を使用または編集して、これらのキーがバインドされているキーを変更できます~/.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