7

У меня есть некоторые экспорты и другие вещи, которые требуют запуска другой программы (чтобы получить пути или что-то еще), и они требуют нетривиального времени для запуска, что означает, что мое время запуска bash составляет порядка 5 секунд.

Прежде чем я уйду и добавлю базовое кэширование в мой .bashrc , есть ли способ, которым я могу выполнить что-то асинхронное, что позволит мне экспортировать переменные в моей работающей оболочке?

(Таким образом, это действительно не ограничивается .bashrc , но bash в целом.)

4 ответа4

2

Многое зависит от того, когда эти программы должны запускаться и когда вам нужны их результаты. Если не имеет значения, когда они запускаются (то есть их результаты не меняются со временем), то может быть лучше, чтобы они запускались из вашего ~/.profile или ~/.bash_profile (то есть, когда вы входите в систему ), а не из вашего ~/.bashrc .

Если вам нужны их результаты, но вы не можете ждать 5 секунд, необходимых для их запуска, что вы будете делать в течение первых 5 секунд, когда ваша оболочка работает? Вы не можете запускать какие-либо команды, которые зависят от результатов этих программ, потому что результаты еще не будут доступны.

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

Все это говорит о том, что вы можете запускать свои программы в фоновом режиме, как предложил Деннис Уильямсон, и попросить их записать свои результаты в некоторые файлы в вашем домашнем каталоге. Затем вы можете установить переменную bash PROMPT_COMMAND для получения исходных файлов, что bash будет делать перед каждым отображением PS1 .

Например, допустим, что ваша фоновая программа записывает export ans=42 в файл ~/answer когда это будет сделано. В вашем ~/.bashrc положите

PROMPT_COMMAND=". ~/answer"

Затем каждый раз, когда оболочка отображает PS1 , она сначала получает исходный ~/answer и ваша среда в конечном итоге (например, через 5 секунд после запуска) будет содержать переменную ans со значением 42 .

Конечно, первые 5 секунд после запуска оболочки ~/answer будут содержать значения, которые использовались в последний раз при запуске оболочки, поэтому вам придется решить, важно ли это (и как сбросить этот файл при необходимости).

1

Я не знаю ни одного способа, который может установить переменные в фоновом режиме. Тем не менее, вы можете запускать сценарии в фоновом режиме, чтобы они выполнялись параллельно, а не последовательно, перехватывая их вывод. Это может ускорить выполнение. Вы можете использовать файловые дескрипторы 3-9 с этим методом для в общей сложности 7 параллельных процессов.

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

Это решение просто позволяет частям скрипта работать параллельно с остальной частью скрипта (в данном случае .bashrc)

function copget { read -u $1; echo "$REPLY"; }

coproc DATE { date; }
exec 3<&${DATE[0]}

coproc UNAME { uname; }
exec 4<&${UNAME[0]}

var1=$(copget 3)
exec 3>&-

var2=$(copget 4)
exec 4>&-
0

Вы можете использовать амперсанд для запуска процесса в фоновом режиме.

some_program &

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

Вы не должны иметь никаких длительных процессов в файлах запуска.

0

Возможно, вы захотите подумать о балансировке рабочей нагрузки между вашим профилем, который выполняется один раз, и вашим файлом bashrc, который выполняется всякий раз, когда вы запускаете (интерактивный) bash. Я держу мой bashrc минимальным - поэтому я быстро запускаюсь. Мой профиль не так уж и плох - он сложный, но, конечно, не занимает 5 секунд.

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