recria a invocação do shell

3

Um shell em execução possui um mecanismo para recriar sua invocação?

Às vezes, faço alterações nas variáveis ou no meu perfil e preciso manualmente source dos arquivos de inicialização para que as coisas sejam executadas novamente, por exemplo, PATH .

Isso se aplica principalmente a shells interativos, suponho.

Eu uso o bash 4 no OS X, mas a questão não está restrita a eles.

    
por 1.61803 20.11.2015 / 18:16

1 resposta

3

Eu faço exec bash . Ele limpa variáveis e funções. Ele não deve limpar os descritores de arquivo recém-abertos (com exec $someNumber<>somefile ) ou as variáveis exportadas, mas eu raramente abro novos arquivos com exec e meus arquivos de inicialização (que são carregados quando você faz exec bash ) restaurar variáveis de ambiente sobre (como PATH ) para o estado em que eu os quero.

( Fazer um bash simples tem a desvantagem de colocar outro shell no seu atual, então você terá que exit mais uma vez. )

Se eu não me preocupo com a limpeza de variáveis e funções extras, eu apenas re-carrego os arquivos de ponto.

Edito ~/.bashrc e o recarrego com bastante frequência, por isso, tenho um atalho de teclado para o combo:

bashrcEdit() { $EDITOR "$HOME/.bashrc"; }
bind -x '"\C-e": bashrcEdit && bashrcReload'

e para recarga simples:

bind -x '"\C-o": bashrcReload;'

( Minha função de recarga é:

bashrcReload() { unset bashrcSourced; unset PROFILE_SOURCED; source "$HOME/.bashrc"; }

em vez de apenas:

source "$HOME/.bashrc";

Ele tem unset s porque essas variáveis (primeiro não exportadas - por .bashrc , segundo exportadas - por .profile ) servem como duplas guardas em minha configuração - sem essas unset s, source ing .bashrc seria um não operacional na minha configuração. )

Fazendo isso direito

Se você quer ser minucioso, você pode

  • tire uma foto do ambiente no final do seu .bashrc (e recarregue-o - isso você pode fazer perfeitamente)
  • instantâneo que os editores de texto estão abertos (e depois feche todos os outros - isto não é e nunca pode ser uma solução perfeita)

Adicione isto no final do seu .bashrc :

#Take a snapshot of the env and fds
envSnap() { 
   export FDS="$(/bin/ls /proc/$$/fd/)"
   export ENV="$(export -p)"
}
#Restore env, close extra fds, and re-exec bash
envRestore(){
  exec env - ENV="$ENV" bash --noprofile -c '
    eval "$ENV"
    for fd in '{ /bin/ls /proc/$$/fd; echo "$FDS"; } | sort | uniq -u'; do
       eval "exec $fd>&-"
    done
    exec bash
   '
}
#Take the snapshot now
envSnap

Agora você pode fazer envRestore para restaurar perfeitamente o ambiente.

Por exemplo, se você:

export FOO=bar
touch file
exec 5<file

Depois de um exec bash , você ainda terá: /bin/ls /proc/self/fd incluem 5 e echo $FOO print bar .

Se você usar envRestore em vez de exec bash , então /bin/ls/ /proc/self/fd não deve incluir 5 (a menos que seu bash geralmente comece com fd 5 aberto) e echo $FOO imprima uma linha vazia.

(Os descritores de arquivo são um ponto fraco disso, porque fechar os descritores de arquivo extras não garante que os descritores de arquivo originais não tenham sido redirecionados ou que as entradas vtable que eles apontam não tenham sido alteradas de uma maneira que mude como lê ou escreve nesse filedescriptor irá se comportar.)

    
por 20.11.2015 / 18:46