zsh медленно делает eval с путем

Добавьте это в конец имеющейся командной строки:

| tr ' ' '\n' 

который заменяет символ пробела новой строкой.

1
24.08.2020, 23:55
1 ответ

Строка 88 функции завершения _cdв текущих версияхzshнаходится в разделе, который доступен только при включенной опции cdablevars.

Если эта опция включена, cd usernameили cd varбудут cdв домашнем каталоге пользователя usernameили в пути, хранящемся в $var, если этот пользователь/переменная существовал и не было username/ varкаталоги в текущем каталоге или $cdpath. Другими словами, cd fooведет себя как cd ~foo, если fooне существует как каталог (в .или$cdpath).

Так вот, это сделано только для cd/ pushd. Когда _cdсоздает список возможных завершений и вы уже ввели Documents/, он должен предложить вам список подкаталогов папки Documents, но также, поскольку вы включили cdablevars, список подкаталогов домашнего каталога пользователя Documentsили каталога, сохраненного в переменной $Documents, если таковые имеются.

Вот почему это происходит eval 'dirs=( ~Documents )'.

Теперь я предполагаю, что расширение может быть медленным, если вы работаете в системе с большой сетевой базой данных пользователей без кэширования, например (LDAP, NIS+... ).zshбудет искать Documentsв своем списке переменных, что должно быть быстро, даже если у вас есть миллионы переменных, поскольку zsh использует хеш-таблицу, и вызовет getpwnam("Documents")для получения домашнего каталога пользователя Documents, который часть, которая, возможно, медленная в вашем случае. Вы можете подтвердить, попробовав id Documents, который должен сделать тот же вызов getpwnam().

Лично я бы избегал этого cdablevarsварианта, так как рано или поздно он преподнесет вам неприятные сюрпризы. Без него вы всегда можете сделать cd ~userили cd ~var, и я считаю, что гораздо лучше запросить его явно, когда вы действительно хотите cdво что-то другое, чем каталог, указанный в качестве аргумента.

Этот cdablevarsуже был в самой первой версии zsh1990 года, вдохновленный tcsh, который делает это по умолчанию. Это предшествует расширению ~var. cdablevarsследует рассматривать как исторический артефакт ИМО.

Что касается того, как исправить медлительность getpwnam(), вы можете посмотреть на настройку базы данных службы имен. Например, при использовании sssdвы можете увеличить параметр entry_negative_timeout, который определяет, как долго кэшировать информацию о том, что пользователь Documentsне существует, прежде чем снова запрашивать серверную часть. 3 секунды в любом случае кажутся чрезмерными для запроса пользовательской базы данных, предполагая, что у вас может быть проблема с конфигурацией или что сервер провайдера недоступен, а резервный механизм, если таковой имеется, не настроен оптимальным образом.

1
18.03.2021, 23:10

Теги

Похожие вопросы