Eu estou querendo saber se existe alguma maneira de colocar algo em meus arquivos de inicialização que fará com que outros arquivos sejam originados após o primeiro prompt ser exibido.
Eu preferiria um método que não dependesse de ganchos como preexec
, precmd
ou periodic
ganchos. (Estou usando o zsh, mas entendo que as pessoas escreveram código para adicioná-los ao bash, por meio de algum hacking inteligente trap
ou algo assim.)
Meu primeiro teste muito simples (que eu não esperava que funcionasse, mas que senti a necessidade de tentar, apenas para ver os resultados precisos) foi adicionar isso ao meu .zshrc
,
{ sleep 100 && export VARIABLE_SET=1 } &
e, em seguida, executando isso após o shell ser carregado, antes e depois de 100 segundos:
echo $VARIABLE_SET
É claro que (e todas as permutações que pude pensar) falharam e não trouxeram pistas promissoras de como isso poderia ser feito.
Era minha esperança que algo do arquivo de inicialização pudesse acionar o sourcing que afeta o shell, mesmo que não esteja imediatamente disponível no primeiro prompt. Quero encontrar uma maneira de atrasar o fornecimento "caro" e fazer com que o prompt apareça rapidamente, já que muitas das coisas que incham os arquivos de inicialização são coisas que não são necessárias com frequência.
Espero encontrar uma abordagem mais simples do que usar ganchos (mas criei uma prova de conceito usando o precmd
gancho caso nenhuma outra abordagem seja possível).
Você não pode usar a
{...} &
ideia porque&
isso faz com que o material seja colocado em um subshell; variáveis definidas lá não afetam o pai.Então, em vez disso, poderíamos gravar as configurações em um arquivo temporário e fazer essa leitura para o pai.
Uma maneira pode ser usar a armadilha DEBUG.
Não totalmente testado, mas talvez algo como
O trap DEBUG normalmente é chamado após a execução de um comando.
Então
Se você deseja obter um
.env
arquivo para carregar variáveis de ambiente, o dotenv pode ajudá-lo.Você sempre pode usar
sched
. Adicione ao seu~/.zshrc
E
~/.zsh/more-stuff
seria originado 30 segundos após o início (ou no próximo prompt após 30 segundos).Como você descobriu, executar comandos em segundo plano com
&
os colocará em um subshell, e um subshell não pode alterar variáveis/variáveis de ambiente do processo pai. (" can't " nesta frase deve ser lido como " as soluções alternativas são feias " .)Portanto, você precisará que o
source
comando seja executado no shell atual. Vou listar algumas opções abaixo.Todos eles não respondem exatamente à pergunta que você fez, mas parecem fornecer soluções para o problema real que você está tentando resolver.
zsh-defer
(script zsh).zshrc
:É possível sinalizar qualquer número de comandos (
source .zshrc.2
,source .zshrc.3
etc.) com chamadas repetidas parazsh-defer
.Benefícios: lida com vários casos extremos que
zinit
não funcionam. Uma solução mais sofisticada do quesched
.Desempenho:
zsh-defer
ele deve carregar dentro de alguns ms no máximo.Implementação: executa os comandos do
zle
(editor de linha do zsh).O
zsh/sched
módulo zsh(como sugerido na resposta anterior por @StéphaneChazelas )
Simplista e direto.
.zshrc
:A
... &>/dev/null || ...
parte: sesched
não estiver disponível, ou sair com um erro, o arquivo é imediatamente originado, sob a suposição de que isso é melhor do que nada.Detalhes sobre
sched
: veja a documentação do zsh .Desvantagens:
Yearly check: do <evil thing>? [y/N]
") enquanto você estiver digitando um comandoDesempenho: o
sched
comando leva no máximo alguns ms para ser executado.Use o prompt powerlevel10k com prompt instantâneo
Não é necessário trabalho extra - faça o que quiser
.zshrc
; o prompt será carregado e pronto para interação (com algumas ressalvas) enquanto.zshrc
estiver sendo processado.Desempenho: o prompt deve estar visível em cerca de 10 ms a partir do momento em que o shell inicia o processamento
.zshrc
.Implementação: vários recursos e truques do zsh. Toma alguns cuidados extras, como redirecionar (e armazenar em buffer) stdin durante a execução de comandos, para evitar entrada acidental.
Gerenciador de plug-ins
zinit
Com
zinit
você pode usarzinit ice wait
para execução adiada de qualquer comando, por exemplo, origem de um arquivo.zinit
pode ser usado apenas para essa funcionalidade, não há necessidade de usá-lo como gerenciador de plugins e não interferirá com outros gerenciadores de plugins, se houver.O original
zdharma/zinit
não é mais mantido, mas esses garfos são:Eu não acho que um comando de longa duração bloqueie o shell, mas eu mesmo não testei isso.
Desempenho: no meu sistema,
zinit
ele carrega em cerca de 10 ms, ou 5 ms sem finalizações.Implementação:
zinit
adiciona uma função shell azsh/sched
, que quando invocada imediatamente se adiciona de volta àsched
tabela e além disso executa os comandos que o usuário configurou, usando ganchos zsh e outros recursos zsh.zsh-async
bibliotecaTambém possivelmente útil - mencionado para completar.
É uma pequena biblioteca geral para executar tarefas assíncronas em zsh. No entanto , ele os executará em um processo separado, que não poderá definir variáveis de ambiente no shell pai. Acredito que existam soluções simples para isso, atribuindo uma função de retorno de chamada que deve permitir a execução de resultados no shell pai.
Benefícios: Bastante amplamente utilizado e mantido ativamente por oito anos.
Implementação: Usa
zsh/zpty
para lançar um pseudo-terminal executando os comandos adiados.Leitura recomendada
romkatv 's (autor de
zsh-defer
e powerlevel10k ) pensamentos gerais e conselhos sobre inicialização zsh em estágio / carregamento lento / execução adiada.Perguntas frequentes sobre o desempenho de carregamento do shell
P: Posso compilar
.zshrc
para wordcode para torná-lo mais rápido?R: É possível em teoria, mas introduz facilmente problemas com aliases, recompilações perdidas e muito mais. Não recomendado.
P: Agora entendo os possíveis problemas. Eu ainda quero tentar isso.
A: Não, realmente, você não.