Завершення вкладки Bash: '-bash: несподіваний EOF під час пошуку відповідності `)' -bash: синтаксична помилка: несподіваний кінець файлу


18

Я намагаюся зайти в irbсеанс із конкретними змінними середовища з файлу з цією командою:

$ env $(cat env.sh) irb

Але коли я намагаюся натиснути Tabпісля введення, env.щоб завершити його, я отримую таку наступну помилку:

$ env $(cat env.-bash: unexpected EOF while looking for matching `)'
-bash: syntax error: unexpected end of file

Ще одна цікава річ у тому, що якщо я зареєстрований як root, ця помилка не виникає.

Ось результат find ~ -uid 0:

$ find ~ -uid 0
/home/(redacted)/.rpmdb
/home/(redacted)/.rpmdb/Group
/home/(redacted)/.rpmdb/Conflictname
/home/(redacted)/.rpmdb/Installtid
/home/(redacted)/.rpmdb/Sha1header
/home/(redacted)/.rpmdb/Providename
/home/(redacted)/.rpmdb/__db.002
/home/(redacted)/.rpmdb/Requirename
/home/(redacted)/.rpmdb/Sigmd5
/home/(redacted)/.rpmdb/__db.001
/home/(redacted)/.rpmdb/Obsoletename
/home/(redacted)/.rpmdb/.dbenv.lock
/home/(redacted)/.rpmdb/Name
/home/(redacted)/.rpmdb/Basenames
/home/(redacted)/.rpmdb/Triggername
/home/(redacted)/.rpmdb/Packages
/home/(redacted)/.rpmdb/Dirnames
/home/(redacted)/.rpmdb/__db.003

Хто-небудь може мені пояснити, чому це відбувається, і якщо так, то як це зробити, коли я не користувач root?


Як увійти як root?
muru

@muru Я ввійшов у root за допомогою sudo su.
eldosoa

Відредагуйте своє запитання, щоб додати результат find ~ -uid 0.
muru

@muru Готово. Додано висновок у моєму запитанні.
eldosoa

Вибачте про це, але не як корінь! Я мав на увазі як ваш звичайний користувач, так це і ~є /home/something.
муру

Відповіді:


33

Ви знайшли помилку в бібліотеці завершення 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злом повинен був виправити ще одну проблему , але я думаю, що він вніс цю іншу помилку в процес.

Як це виправити?

Виявляється, про цю помилку вже повідомлялося . Прочитавши цей звіт про помилку, я бачу три способи виправити:

  1. Виправити це: в одному з коментарів у звіті про помилку, хтось пропонує замінити рядок

    [[ ${!2} == \$* ]] && eval $2=${!2}

    в межах функції _quote_readline_by_refу файлі /usr/share/bash-completion/bash_completionпо рядку

    [[ ${!2} == \$\'* ]] && eval $2=${!2}

    Я не рекомендую цього робити. Людина, яка написала цей коментар, не виявляється розробником bash-завершення . Це виправлення просто призведе до того, що лівий операнд висловлювання оцінюється як хибний, і, таким чином, запобігає цьому eval. Однак без хорошого знання того, що ця функція повинна виконувати і в яких контекстах вона називається, незрозуміло, чи це потенційно не може порушити якусь іншу призначену функціональність.

  2. Отримайте найновішу версію: Як також згадувалося у звіті про помилку, ця помилка не присутня в 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.

  1. Сядьте і чекайте: рано чи пізно нова версія буде випущена (що може навіть виправити завершення bash всередині підстановки команд), і ви отримаєте її з деякою майбутнім версією Ubuntu. Ось за що я йду ;-)

1
@ con-f-використання Так, це все! Репортаж Git також пов'язаний з основним сайтом завершення bash, тому я у своїй відповіді не зв’язався з цим.
Malte Skoruppa

2
@ con-f-use Ваш коментар змусив мене ще кілька досліджень щодо цієї помилки. Виявляється, це не був і ніколи не був помилкою вище. Натомість це фактично помилка, введена патчем Ubuntu, застосованим проти версії upstream. Здається, ніхто поки що не звузив цю помилку до цього конкретного виправлення. Тож я повідомив про свої знахідки у відповідному звіті про помилки Ubuntu: bugs.launchpad.net/ubuntu/+source/bash-completion/+bug/1312243 .
Malte Skoruppa

2
Приємна робота Мальте.
Barry Kelly

1
Дякую за пояснення. На момент написання цієї версії версія git head видалила помилку та автоматично завершує роботу за бажанням. EDIT: насправді, ніколи, це не так.
користувач3391564

1
@MaxvonHippel Я сказав , що , коли ви використовуєте , sudo suщоб стати коренем, що не підключить бібліотеку, але він буде отримувати джерела , коли ви використовуєте sudo -iзамість цього, що передбачуваний спосіб отримати інтерактивний кореневої сеанс. Що стосується вашого запитання: Оскільки будь- ~/.bashrcяка команда bash читає, що в кінцевому рахунку джерело бібліотеки, і немає ніякого способу "un-source" файл, я не бачу абсолютно прямого шляху. Ось можливий злом: Зробіть джерело бібліотеки NOCOMPL~/.bashrc
залежною
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.