Ви знайшли помилку в бібліотеці завершення Bash, яку використовує Ubuntu.
Що це означає?
Ubuntu використовує бібліотеку завершення bash, щоб зробити інтелектуальне завершення. Ця бібліотека живе в /usr/share/bash-completion/bash_completion.
По суті, ця бібліотека декларує кілька розумних функцій, які знають про типові команди та способи їх виконання. Щоразу, коли ви натискаєте Tab, функції цієї бібліотеки викликають і намагаються завершити поточний командний рядок. Так, наприклад, якщо ви набираєте текстapt-get iTab його, ви завершите це apt-get install. Якщо ви не використовуєте джерело цієї бібліотеки, у вас є лише стандартне, примітивне завершення bash - так, наприклад, якщо ви вводите apt-get iTabбез отримання джерела, 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. Ось за що я йду ;-)