15

Запуск bash в моей системе Ubuntu занимает около 2 секунд. Если я удаляю загрузку /etc /bash_completition в .bashrc, она начинается без задержки. Конечно, я не хочу отказываться от завершения и не думаю, что загрузка этого файла является законной причиной задержки в 2 секунды.

Любые идеи, как я могу узнать, в чем проблема или как я могу ускорить процесс.

4 ответа4

12

Я нашел немного хакерское решение, которое, кажется, работает достаточно.

Решение

Внизу ~/.bashrc добавьте:

trap 'source /etc/bash_completion ; trap USR1' USR1
{ sleep 0.1 ; builtin kill -USR1 $$ ; } & disown

объяснение

trap 'source /etc/bash_completion ; trap USR1' USR1

Настройте обработчик для запуска, когда оболочка получает сигнал SIGUSR1 ; обработчик загрузит завершения и, следовательно, сам деактивируется.

{ sleep 0.1 ; builtin kill -USR1 $$ ; } & disown

Немного асинхронно подождите, а затем отправьте сигнал текущей оболочке. disown необходимо для подавления обратной связи управления процессом bash . sleep нужен, чтобы работать асинхронно.

Проблемы

По какой-то причине первая команда, выданная этой оболочке, не будет записана в историю.

8

Обновление в 2013 году: большая часть завершения bash была переписана для завершения автозагрузки только при необходимости. Базовый сценарий теперь намного легче.


Скрипт завершения иногда может быть огромным в стандартах сценария оболочки. На одном из серверов, к которому у меня есть доступ, это почти 1700 строк (57 КБ), и это только основной скрипт. В /etc/bash_completion.d есть ~ 200 дополнительных сценариев для различных других команд (openssl , mutt , mount ...) общим объемом 25537 строк или 1,2 МБ. Каждый скрипт при получении проверяет, доступна ли команда на самом деле, прежде чем определять обработчики завершения; ~ 330 раз в этом случае, каждый из которых включает проверку $PATH для исполняемого файла с заданным именем. (Хотя я ожидаю, что /usr/bin будет кэшироваться в памяти ...)

По общему признанию, даже это занимает только полсекунды для загрузки, а не две полных секунды. Но это может быть хотя бы частью проблемы. Запустите du -hs /etc/bash_completion* или wc -l /etc/bash_completion average ,.d/* wc -l /etc/bash_completion{,.d/*} | grep total если хотите проверить.


Вы можете попробовать поискать скрипт вручную в режиме "трассировки":

set -x
. /etc/bash_completion

Вы увидите каждую строку, как она выполняется. Если есть определенная команда, которая занимает много времени, вы должны это заметить.

(set +x отключает режим трассировки.)

5

Вы должны использовать последнюю версию (2.0) bash_completion. Если вы используете Debian, он находится в wheezy, но он не зависит от любого другого пакета wheezy, поэтому вы можете установить его без проблем.

Самая последняя версия загружает завершение динамически на лету, поэтому оно делило для меня время быстрой загрузки по крайней мере в 10 раз.

1

Вы можете использовать заполнитель во время загрузки завершений; этого должно быть достаточно, чтобы обмануть ваши глаза. Это, очевидно, работает, только если время, требуемое source /etc/bash_completion , меньше, чем время, необходимое вам для ввода и выдачи первой команды оболочки, в противном случае оно также будет отложено.

Идея состоит в том, чтобы повторить поддельный PS1 , получить завершение и, наконец, ослабить терминал.

Предположим, что ваш PS1 \u@\h:\w\$ , вы можете написать что-то вроде:

echo -ne "$USER@$HOSTNAME:${PWD/$HOME/\~}\$ "
source /etc/bash_completion
echo -ne '\e[2J\e[H'

Куда:

  • 2J стирает терминал;
  • H переместите курсор в верхний правый угол.

Примечание: вы можете проверить, является ли пользователь root и использовать # вместо $ для согласованности:

echo -ne "...$([ $UID = 0 ] && echo '#' || echo '$') "

Примечание. Удаление \e[2J позволяет избежать мерцания, но оставляет ненужные символы, если заполнитель длиннее, чем фактическое приглашение.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .