Я пытаюсь войти в 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?
command-line
bash
auto-completion
eldosoa
источник
источник
sudo su
.find ~ -uid 0
.~
это/home/something
.Ответы:
Вы нашли ошибку в библиотеке 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
.Почему эта ошибка происходит?
Попробуйте выполнить эту команду:
Выглядит знакомо? ;-) Действительно, именно это и произошло, когда вы попали Tabв контекст, который вы описали. Точнее, ошибка в
_quote_readline_by_ref
объявленной функции/usr/share/bash-completion/bash_completion
. Если вы получили этот файл, у вас должна быть доступна эта функция. Итак, попробуйте следующее:Учитывая эти аргументы, функция
_quote_readline_by_ref
выполняет, помимо прочего, чтоeval
упомянуто выше. Вы можете посмотреть, если хотите. И когда вы печатаетеenv $(cat env.
Tab, за кулисами эта функция вызывается именно с этими аргументами. Так вот что случилось.Этот
eval
хак должен был исправить другую проблему , но я предполагаю, что в процессе появилась другая ошибка.Как мне это исправить?
Оказывается, об этой ошибке уже сообщалось . После прочтения этого сообщения об ошибке я вижу три способа исправить это:
Исправьте это: в одном из комментариев в этом отчете об ошибках кто-то предлагает заменить строку
внутри функции
_quote_readline_by_ref
в файле/usr/share/bash-completion/bash_completion
по строкеЯ рекомендую не делать этого. Человек, написавший этот комментарий, не является разработчиком bash-complete . Это исправление просто приведет к тому, что левый операнд оператора оценивается как ложное, и, таким образом, предотвратит это
eval
. Однако без хорошего знания того, что эта функция должна делать и в каких контекстах она вызывается, неясно, не нарушит ли она какую-либо другую предполагаемую функциональность.Получите самую последнюю версию: Как также упоминалось в этом отчете об ошибке, эта ошибка отсутствует в git head (где, помимо других изменений, функция
_quote_readline_by_ref
была упрощена). Вы можете просто клонировать текущую ревизию из Git:... и затем скопируйте самую новую версию
bash_completion
скрипта в/usr/share/bash-completion
(нет необходимости в срочном резервном копировании старой версии, если это не заставит вас чувствовать себя в безопасности - если у вас возникнут какие-то проблемы,sudo apt-get install --reinstall bash-completion
следует отменить любые внесенные вами изменения.) Так я рекомендую, если вы спешите исправить это. :-)Обратите внимание, что ни одно из этих решений не выполнит завершение bash внутри подстановки команд: как упоминалось в том же отчете об ошибках, это не работает в Bash 4.3.
источник
sudo su
чтобы стать корнем, не подключит библиотеку, но он будет получать источники , когда вы используетеsudo -i
вместо этого, что предполагаемый способ получить интерактивный корневой сеанс. Что касается вашего вопроса: поскольку любая оболочка bash читает,~/.bashrc
что в конечном итоге является источником библиотеки, и нет никакого способа «удалить исходный код» файла, я не вижу абсолютно простого способа. Вот возможный хак: сделайте источник библиотеки условным для некоторой переменной среды, скажемNOCOMPL
, не определяемой в вашем~/.bashrc
,