Ви знайшли помилку в бібліотеці завершення Bash, яку використовує Ubuntu.
Що це означає?
Ubuntu використовує бібліотеку завершення bash, щоб зробити інтелектуальне завершення. Ця бібліотека живе в /usr/share/bash-completion/bash_completion
.
По суті, ця бібліотека декларує кілька розумних функцій, які знають про типові команди та способи їх виконання. Щоразу, коли ви натискаєте Tab, функції цієї бібліотеки викликають і намагаються завершити поточний командний рядок. Так, наприклад, якщо ви набираєте текстapt-get i
Tab його, ви завершите це apt-get install
. Якщо ви не використовуєте джерело цієї бібліотеки, у вас є лише стандартне, примітивне завершення bash - так, наприклад, якщо ви вводите apt-get i
Tabбез отримання джерела, bash просто шукатиме файли в поточному каталозі, починаючи з i
і намагається виконати свою команду відповідно до ці назви файлів.
Чому це не відбувається як корінь?
Тому що, коли ви використовуєте sudo su
для виготовлення себе root
, бібліотека завершення башів не надається. Це було б інакше, якби ви використовувалиsudo -i
робив себе root
. Надіюсь, ви бачите помилку тоді, чи не так? Дивіться, наприклад, 'sudo su -' vs 'sudo -i' vs 'sudo / bin / bash' - коли важливо, що використовується, чи це взагалі має значення? якщо ви не знайомі з відмінностями.
У моєму випадку, як звичайний користувач, бібліотека отримує джерело, коли я запускаю оболонку Bash, оскільки ~/.bashrc
джерела, /etc/bash_completion
які джерела /usr/share/bash-completion/bash_completion
.
Якщо я використовую sudo -i
для входу як root
, бібліотека отримується через /etc/profile
джерела/etc/profile.d/bash_completion.sh
які джерела /usr/share/bash-completion/bash_completion
.
Чому трапляється ця помилка?
Спробуйте виконати цю команду:
$ eval 'quoted=$(cat' env.
bash: unexpected EOF while looking for matching `)'
bash: syntax error: unexpected end of file
Виглядає знайомо? ;-) Дійсно, саме це сталося за кадром, коли ви потрапили Tabв описаний вами контекст. Точніше, помилка знаходиться у функції, яку _quote_readline_by_ref
оголошує /usr/share/bash-completion/bash_completion
. Якщо ви знайшли цей файл, ви повинні мати цю функцію. Тож спробуйте наступне:
$ _quote_readline_by_ref '$(cat env.' quoted
bash: unexpected EOF while looking for matching `)'
bash: syntax error: unexpected end of file
Враховуючи ці аргументи, функція _quote_readline_by_ref
виконує, серед іншого, і те, що eval
згадувалося вище. Ви можете подивитися, якщо вам подобається. А коли ви вводили env $(cat env.
Tab, за кадром цю функцію викликали саме ці аргументи. Так ось і сталося.
Цей eval
злом повинен був виправити ще одну проблему , але я думаю, що він вніс цю іншу помилку в процес.
Як це виправити?
Виявляється, про цю помилку вже повідомлялося . Прочитавши цей звіт про помилку, я бачу три способи виправити:
Виправити це: в одному з коментарів у звіті про помилку, хтось пропонує замінити рядок
[[ ${!2} == \$* ]] && eval $2=${!2}
в межах функції _quote_readline_by_ref
у файлі /usr/share/bash-completion/bash_completion
по рядку
[[ ${!2} == \$\'* ]] && eval $2=${!2}
Я не рекомендую цього робити. Людина, яка написала цей коментар, не виявляється розробником bash-завершення . Це виправлення просто призведе до того, що лівий операнд висловлювання оцінюється як хибний, і, таким чином, запобігає цьому eval
. Однак без хорошого знання того, що ця функція повинна виконувати і в яких контекстах вона називається, незрозуміло, чи це потенційно не може порушити якусь іншу призначену функціональність.
Отримайте найновішу версію: Як також згадувалося у звіті про помилку, ця помилка не присутня в git head (де серед інших змін функцію _quote_readline_by_ref
було спрощено). Ви можете просто клонувати поточну версію з Git:
git clone https://salsa.debian.org/debian/bash-completion.git
... а потім скопіюйте найновішу версію bash_completion
сценарію /usr/share/bash-completion
(не потрібно терміново створювати резервну копію старої версії, якщо це не робить вас більш безпечним. Якщо у вас виникнуть проблеми, sudo apt-get install --reinstall bash-completion
слід відновити будь-які внесені вами зміни.) Це я так рекомендуємо, якщо ви поспішаєте виправити це. :-)
Зауважте, що жодне з цих рішень не дозволить виконати bash в роботі заміни команд: як зазначено в тому самому звіті про помилку, це порушено в Bash 4.3.
- Сядьте і чекайте: рано чи пізно нова версія буде випущена (що може навіть виправити завершення bash всередині підстановки команд), і ви отримаєте її з деякою майбутнім версією Ubuntu. Ось за що я йду ;-)