
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
_
関数に入るとすぐに保存する必要があります:
。はヌル コマンドで、それ自体は何も行いませんが、 の設定などのコマンドの通常の副作用があります_
。この復元操作は、潜在的に混乱を招く可能性のある各関数の各戻りポイントで必要になります。ここでも微妙な点があります。通常、 は_
関数から戻った直後に設定されます (予想どおり、関数呼び出しの最後の引数に設定されます)。そのため、この方法は無効になります。ただし、補完関数が呼び出された場合は、明示的に呼び出されないため、この処理は行われません。これはあまり堅牢ではないと思います...
(私は歴史の拡大、そして!$
この問題の影響を受けないものに固執してください。