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