Bash запускается медленно из-за этой строки в .bashrc. Что может вызвать это?

19

Мой .bashrcфайл содержит строку с этим эффектом:

alias prog="/path/to/script.sh $(find $(pwd) -name prog)"

Когда я закомментирую эту строку, Bash запускается практически мгновенно, когда я открываю новый терминал. В этой строке задержка составляет 4-5 секунд, прежде чем появляется мой курсор.

Удаление вложенных команд $(pwd)и т. Д. Также ускоряет его. Почему это происходит? Можно ли как-то использовать вложенные команды?

BBales
источник
4
Проблема заключается в findкоманде, которая выполняется во время загрузки и может занять много времени, в зависимости от структуры каталогов. Если вы используете одинарные вместо двойных кавычек, findбудет выполняться во время выполнения, когда aliasвызывается. Это зависит от того, какой рабочий каталог вы хотите использовать, этот текущий во время объявления или во время выполнения. Кстати, $(pwd)довольно неэффективный способ выразить .или $PWD.
AFH
15
Я знаю, что это не то, что вы спрашиваете, но это очень похоже на проблему XY . Зачем вам нужно найти скрипт с помощью find? Как только вы установили его, вы знаете, где он находится. Даже если вы часто обновляете его и меняете его имя, вы можете сохранить символическую ссылку на него, чтобы он всегда был доступен под фиксированным именем.
слеске
5
@AFH Пожалуйста, отправляйте ответы как ответы, а не комментарии.
Дэвид Ричерби,
1
@DavidRicherby - я хотел убедиться, что это был действительно ответ перед публикацией. Я был озадачен тем, что скрипт будет работать с файлами, найденными в произвольном каталоге.
AFH

Ответы:

45

Поскольку подстановка команды находится в двойных кавычках, она оценивается во время определения команды. Это заставляет findпросматривать содержимое вашего жесткого диска во время .bashrcработы.

Вы, напротив, похоже, хотите, чтобы оно оценивалось во время использования. В этом случае используйте одинарные кавычки:

alias prog='/path/to/script.sh $(find "$(pwd)" -name prog)'

Обратите внимание, что этот псевдоним потерпит неудачу, если у любого из найденных файлов будут пробелы в именах. Чтобы избежать этого:

alias prog='find . -name prog -exec /path/to/script.sh {} +'

Эта последняя форма будет надежно работать для любого типа имени файла.

John1024
источник
1
«время использования». И твоя вторая строка избегает порождения под раковиной.
rleir
11
С другой стороны, теперь каждый раз, когда вы печатаете prog, findнужно будет запускаться, тогда как раньше он запускался только один раз (при запуске оболочки).
el.pescado
Опять же, из-за кэширования файлов, во второй раз, когда вы запускаете то же самое find, обычно это происходит намного быстрее.
reinierpost
21
@ el.pescado С другой стороны, трудно представить, что предполагаемое поведение - запускать команду для файлов, которые существовали на момент входа пользователя в систему, а не для файлов, которые существуют, когда они выполняли команду для их обработки.
Дэвид Ричерби,
2
@DavidRicherby Может быть, мы можем кэшировать путь progи перезапустить, findесли старый путь больше не существует?
Алекс Вонг