Все ответы относятся к более старым версиям bash_completion и не имеют отношения к последним bash_completion
.
Современный bash_completion переместил большинство файлов завершения в /usr/share/bash-completion/completions
по умолчанию, проверьте путь в вашей системе, запустив
# pkg-config --variable=completionsdir bash-completion
/usr/share/bash-completion/completions
Там много файлов, по одному на каждую команду, но это не проблема, так как они загружаются по запросу при первом использовании автодополнения для каждой команды. Старый /etc/bash_completion.d
по-прежнему поддерживается для совместимости, и все файлы оттуда загружаются при запуске bash_completion
.
# pkg-config --variable=compatdir bash-completion
/etc/bash_completion.d
Используйте этот скрипт, чтобы проверить, не остались ли устаревшие файлы в старом каталоге.
#!/bin/sh
COMPLETIONS_DIR="$(pkg-config --variable=completionsdir bash-completion)"
COMPAT_DIR="$(pkg-config --variable=compatdir bash-completion)"
for file in "${COMPLETIONS_DIR}"/*; do
file="${COMPAT_DIR}/${file#${COMPLETIONS_DIR}/}"
[ -f "$file" ] && printf '%s\n' $file
done
Он печатает список файлов в каталоге совместимости, которые также присутствуют в более новом (по запросу) каталоге дополнений. Если у вас нет конкретных причин для сохранения некоторых из них, просмотрите, создайте резервную копию и удалите все эти файлы.
В результате каталог совместимости должен быть в основном пуст.
Теперь самое интересное - проверка почему bash
тормозит запуск. Если вы просто запустите bash
, он запустит интерактивную интерактивную оболочку без входа в систему — сначала исходный код Cygwin /etc/bash.bashrc
, а затем ~/.bashrc
. Скорее всего, это не включает завершение bash, если вы не используете его из одного из файлов rc. Если вы запустите bash -l
(bash --login
), запустите Cygwin Terminal
(зависит от вашего cygwin.bat
) или войдете через SSH, он запустит интерактивную интерактивную оболочку, которая будет источником /etc/profile
, ~/.bash_profile
и вышеупомянутого rc файлы. Сам сценарий /etc/profile
содержит все исполняемые файлы .sh
в папке /etc/profile.d
.
Вы можете проверить, сколько времени требуется каждому файлу для получения исходного кода. Найдите этот код в /etc/profile
:
for file in /etc/profile.d/*.$1; do
[ -e "${file}" ] && . "${file}"
done
Сделайте резервную копию, а затем замените на это:
for file in /etc/profile.d/*.$1; do
TIMEFORMAT="%3lR ${file}"
[ -e "${file}" ] && time . "${file}"
done
Запустите bash
, и вы увидите, сколько времени занял каждый файл. Исследуйте файлы, которые занимают значительное количество времени. В моем случае это были bash_completion.sh
и fzf.sh
(fzf — нечеткий поиск, действительно хорошее дополнение к bash_completion). Теперь выбор состоит в том, чтобы отключить его или продолжить расследование. Поскольку я хотел продолжать использовать ярлыки fzf
в bash, я исследовал, нашел источник замедления, оптимизировал его и отправил свой патч в репозиторий fzf (надеюсь, он будет принят).
Теперь самое большое времяпрепровождение - bash_completion.sh
. По сути, этот сценарий исходит из /usr/share/bash-completion/bash_completion
. Я сделал резервную копию этого файла, а затем отредактировал его. На последней странице есть цикл for
, который получает все файлы в каталоге compat
- /etc/bash_completion.d
. Я снова добавил TIMEFORMAT
и time
и увидел, какой скрипт вызывает медленный запуск. Это был zzz-fzf
(пакет fzf
). Я исследовал и обнаружил, что подоболочка ($()
) выполняется несколько раз в цикле for
, переписал эту часть без использования подоболочки, что позволило скрипту работать быстро. Я уже отправил свой патч в репозиторий fzf.
Основная причина всех этих замедлений заключается в следующем: fork
не поддерживается моделью процессов Windows, Cygwin отлично справился с ее эмуляцией, но она мучительно медленная по сравнению с реальной UNIX. Подоболочка или конвейер, который выполняет очень мало работы сам по себе, тратит большую часть времени выполнения на fork
-ing. Например. сравните время выполнения time echo msg
(0,000 с на моем Cygwin) и time echo $(echo msg)
(0,042 с на моем Cygwin) - днем и ночью. Сама команда echo
не требует заметного времени для выполнения, но создание подоболочки обходится очень дорого. В моей системе Linux эти команды занимают 0,000 с и 0,001 с соответственно. Многие пакеты Cygwin разработаны людьми, использующими Linux или другие UNIX, и могут работать на Cygwin без изменений. Поэтому, естественно, эти разработчики не стесняются использовать подоболочки, конвейеры и другие функции везде, где это удобно, поскольку они не чувствуют значительного снижения производительности своей системы, но на Cygwin эти сценарии оболочки могут работать в десятки и сотни раз медленнее.
Итог, если сценарий оболочки работает медленно в Cygwin - попробуйте найти источник вызовов fork
и перепишите сценарий, чтобы максимально их устранить. Например. cmd="$(printf "$1" "$2")"
(использует одну вилку для подоболочки) можно заменить на printf -v cmd "$1" "$2"
.
Блин, получилось очень долго. Все, кто дочитал до этого места, — настоящие герои. Спасибо :)
person
Gene Pavlovsky
schedule
23.04.2016
--startuptime
и что не так с этим .bashrc. Вам повезет, если вы зададите каждый вопрос отдельно, а для второго вопроса объясните, что конкретно идет не так. - person me_and   schedule 21.03.2013--startuptime
для bash нигде на странице руководства, а также в Интернете. Я думаю, что эти вопросы сочетаются друг с другом, поэтому я задал их вместе. - person Forethinker   schedule 23.03.2013Bash loads slowly in Cygwin
? Дело не в вашем английском, а в том, чтобы сделать хороший вопрос еще лучше. - person ForceBru   schedule 11.03.2015