Вы нашли ошибку в библиотеке Bash Completion, используемой Ubuntu.
Что это значит?
Ubuntu использует библиотеку завершения bash, чтобы сделать завершение bash разумным. Эта библиотека живет в /usr/share/bash-completion/bash_completion
.
По сути, эта библиотека объявляет несколько умных функций, которые знают о типичных командах и о том, как их выполнять. Всякий раз, когда вы нажимаете Tab, функции в этой библиотеке вызывают и пытаются завершить текущую командную строку. Так, например, если вы напечатаете, apt-get i
Tabэто завершит это до apt-get install
. Если вы не используете эту библиотеку, у вас есть только стандартное примитивное завершение bash - так, например, если вы печатаете apt-get i
Tabбез использования источника, bash просто ищет файлы в текущем каталоге, начиная с, i
и пытается выполнить команду в соответствии с эти имена файлов.
Почему это не происходит как root?
Потому что когда вы используете sudo su
для создания себя root
, библиотека завершения bash не поставляется. Это было бы иначе, если бы ты sudo -i
делал сам root
. Бьюсь об заклад, вы видите ошибку, не так ли? Посмотрите, например, «sudo su -» против «sudo -i» против «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-complete . Это исправление просто приведет к тому, что левый операнд оператора оценивается как ложное, и, таким образом, предотвратит это 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. Вот для чего я иду ;-)