web-dev-qa-db-ja.com

自動補完が有効な場合、シェルはプロンプトを表示しません(代わりにカーソルが点滅します)

.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

ただし、これには副作用があります。オートコンプリートは機能しているように見えますが、新しいターミナルを開くと、点滅するカーソルのみが表示されます。

enter image description here

user@machine:~$を押した後にのみ、通常のCtrl+Cプロンプトに戻ります。

上記の行をコメントすると、通常の動作に戻ります(ただし、オートコンプリートはもうありません)。

問題が何なのかわかりません。

-更新1-

コードの機能は次のとおりです。

enter image description here

-更新2-

推奨コマンドの出力は次のとおりです。何かがループし続け、ターミナルがouptutであふれます。

++++++ : /etc/bash_completion.d
++++++ readonly BASH_COMPLETION_COMPAT_DIR
++++++ _blacklist_glob='@(acroread.sh)'
++++++ shopt -s extglob progcomp
++++++ complete -d pushd
++++++ complete -u write chfn groups slay w sux runuser
++++++ complete -A stopped -P '"%' -S '"' bg
++++++ complete -j -P '"%' -S '"' fg jobs disown
++++++ complete -v readonly unset
++++++ complete -A setopt set
++++++ complete -A shopt shopt
++++++ complete -A helptopic help
++++++ complete -a unalias
++++++ complete -A binding bind
++++++ complete -c command type which
++++++ complete -b builtin
++++++ [[ linux-gnu == *@(solaris|aix)* ]]
++++++ [[ linux-gnu == *@(solaris|aix)* ]]
++++++ [[ linux-gnu == *@(solaris|aix)* ]]
++++++ _backup_glob='@(#*#|*@(~|.@(bak|orig|rej|swp|dpkg*|rpm@(orig|new|save))))'
++++++ complete -F _service service
++++++ _sysvdirs
++++++ sysvdirs=()
++++++ [[ -d /etc/rc.d/init.d ]]
++++++ [[ -d /etc/init.d ]]
++++++ sysvdirs+=(/etc/init.d)
++++++ [[ -f /etc/slackware-version ]]
++++++ for svcdir in '${sysvdirs[@]}'
++++++ for svc in '$svcdir/!($_backup_glob)'
++++++ [[ -x /etc/init.d/acpid ]]
++++++ complete -F _service /etc/init.d/acpid
++++++ for svc in '$svcdir/!($_backup_glob)'
++++++ [[ -x /etc/init.d/anacron ]]
++++++ complete -F _service /etc/init.d/anacron
++++++ for svc in '$svcdir/!($_backup_glob)'
++++++ [[ -x /etc/init.d/apparmor ]]

-更新3-

要求された出力は次のとおりです。

ac@ac:~$ grep -r bash_completion /etc/bash_completion.d
/etc/bash_completion.d/bash.bashrc:#  if [ -f /usr/share/bash-completion/bash_completion ]; then
/etc/bash_completion.d/bash.bashrc:#    . /usr/share/bash-completion/bash_completion
/etc/bash_completion.d/bash.bashrc:#  Elif [ -f /etc/bash_completion ]; then
/etc/bash_completion.d/bash.bashrc:#    . /etc/bash_completion
/etc/bash_completion.d/bash.bashrc.bak:#  if [ -f /usr/share/bash-completion/bash_completion ]; then
/etc/bash_completion.d/bash.bashrc.bak:#    . /usr/share/bash-completion/bash_completion
/etc/bash_completion.d/bash.bashrc.bak:#  Elif [ -f /etc/bash_completion ]; then
/etc/bash_completion.d/bash.bashrc.bak:#    . /etc/bash_completion
/etc/bash_completion.d/inkscape:# put this file in /etc/bash_completion.d/ 
/etc/bash_completion.d/desktop-file-validate:# put this file in /etc/bash_completion.d/
/etc/bash_completion.d/bash_completion~:. /usr/share/bash-completion/bash_completion
/etc/bash_completion.d/git-completion.bash:#   bash_completion - programmable completion functions for bash 3.2+
/etc/bash_completion.d/libreoffice.sh:# Programmable bash_completion file for the main office applications
/etc/bash_completion.d/bash_completion:# . /usr/share/bash-completion/bash_completion

実際、最後の行はあなたが予測したことを示しています。しかし、そのファイルをどうすればよいのかわかりません。削除する必要がありますか、それとも誤って上書きしましたか?もしそうなら、元のコンテンツは何でしたか?

4

set -xで得られる出力に非常に多くのプラス記号(++++++)が含まれているという事実は、/ usr/share/bash-completion/bash_completionが再帰的に再ソースされていることを意味します。

つまり、/ usr/share/bash-completion/bash_completionは自分自身を「呼び出し」ており、前述のように無限ループのようなものになります。

もし私があなただったら、/ etc/bash_completion.dへの参照を探します/ usr/share/bash-completion/bash_completion。具体的には、次のようにします。

  1. ls -l /etc/bash_completion.d/ usr/share/bash-completion/bash_completionへのシンボリックリンクがあってはなりません);
  2. grep -r bash_completion /etc/bash_completion.d/ etc/bash_completion.dのファイルはどれも/ usr/share/bash-completion/bash_completionをソースとする必要があります)。

または、シェルで次の2つのコマンドを実行できます(もちろん、bash補完を有効にしないでください)。

set -x
. /usr/share/bash-completion/bash_completion |& grep -E "^\++ (\.|source)"

これにより、すべての「インポート」が出力され、問題の原因となっている厄介なコードの特定に役立ちます。


grep -r bash_completion /etc/bash_completion.dの出力から、多くの一致を確認できます。それらのほとんどはコメントです(#で始まるため)が、興味深い行があります:

/etc/bash_completion.d/bash_completion~:. /usr/share/bash-completion/bash_completion

/ etc/bash_completion.d/bash_completion〜が原因です。これは、再帰的リソースの原因となっているファイルです。

/ usr/share/bash-completion/bash_completion実際、/ etc/bash_completion.dディレクトリ内のすべてのファイルを自動的にソースします。しかし、あなたの場合、このディレクトリにはbash_completion〜ファイルが含まれています。このファイルは/ usr/share/bash-completion/bash_completionを再びソースしています。これにより、ループが発生します。

だから、それを削除してください!

Sudo rm /etc/bash_completion.d/bash_completion~

(または、何か有用なものが含まれていると思われる場合は読んでください。)

そのファイルがそのディレクトリにあった理由を説明することはできません。私があなたに言えることは、接尾辞~はこれがバックアップファイルであることを意味するということです。多くのテキストエディター(Geditを含む)は、保存時にバックアップコピーを作成します。おそらく、変更中に誤ってそこに残っていたのでしょう。

3

デバッグのために、いくつかのecho行を追加して、コードがどこまで到達するかを確認できます。私はそれがそこのある時点で壊れていると仮定していますが、それは非常に大声でそれをしていないだけです。

次のようなものに置き換えます。

 if ! shopt -oq posix; then
   echo Entering bash-completion load
   if [ -f /usr/share/bash-completion/bash_completion ]; then
     echo Sourcing /usr/share/bash-completion/bash_completion
     . /usr/share/bash-completion/bash_completion
     echo Sourced
   Elif [ -f /etc/bash_completion ]; then
     echo Sourcing /etc/bash_completion
     . /etc/bash_completion
     echo Sourced
   fi
 fi
 echo Done

理想的な世界では次のように表示されます:

Entering bash-completion load
Sourcing /usr/share/bash-completion/bash_completion
Sourced
Done

Bash_completionスクリプトに引っかかっている場合は、デバッグをオンにして手動でソースを取得します(これは端末がまだ機能していることを前提としています)。

set -x
. /usr/share/bash-completion/bash_completion

それは壊れる(または終了する)まで出力されるべきであり、実際の問題が何であるかの別の指標を与えるはずです。

3
Oli