Não é possível obter com êxito o .bashrc a partir de um script de shell

34

Normalmente, podemos fornecer ~/.bashrc file usando este comando

source ~/.bashrc

mas se eu escrever isso em um shell script e executá-lo, nada acontecerá. Por quê?
Existe alguma maneira de fazer isso?

meu código de shell:

#!/bin/bash
chmod a+x ~/.bashrc
source ~/.bashrc

Também tentei .[dot] em vez de source . Mesmo resultado

    
por shantanu 05.10.2011 / 13:50

5 respostas

22

Um script de shell é executado em sua própria instância de shell. Todas as configurações de variáveis, definições de funções e tais afetam apenas essa instância (e talvez seus filhos), mas não o shell de chamada, de modo que elas desaparecem depois que o script é concluído.

Por contraste, o comando source não inicia uma nova instância de shell, mas usa o shell atual para que as alterações permaneçam.

Se você quiser que um atalho leia seu .bashrc, use uma função de shell ou um alias em vez de um script de shell, como

alias brc='source ~/.bashrc'
    
por Florian Diesch 05.10.2011 / 14:16
13

Tente:

exec bash

Isso deve recarregar ~ / .bashrc, ~ / .bash_aliases, etc.

    
por Alin Andrei 05.10.2011 / 14:37
7

Seu .bashrc geralmente começa:

# If not running interactively, don't do anything
[ -z "$PS1" ] && return

Como o script não possui o PS1 definido (porque não é interativo), ele não redefine o caminho porque sai antes. Para demonstrar, modifique seu script:

    #!/bin/bash
    chmod a+x ~/.bashrc
    PS1='$ '
    source ~/.bashrc

isso agora permitirá que seus scripts funcionem com o novo .bashrc . Nota: depois que o seu script sair, o env será configurado para o que era antes de iniciar o script. As alterações serão refletidas na próxima vez que um terminal for iniciado.

    
por ravi nankani 08.11.2011 / 12:11
2

Nenhum dos outros métodos funcionou para mim [ source /path/to/file vs . ./path/to/file , alias, etc ...], até que, graças a este tutorial descobri que usando o:

#!/usr/bin/env bash shebang

em vez do #!/usr/bin/env mais simples, permite que os argumentos passem para o interpretador, o que eu acho que é a chave aqui - veja este documento para mais informações.

Em qualquer caso, se os comandos de origem de qualquer forma não estiverem funcionando para você, tente verificar seu shebang, que pode ser o problema:)

    
por Nikksno 21.08.2016 / 03:40
0

Eu quero complementar a resposta do ravi :

Esse comportamento é específico para o Ubuntu (e provavelmente para as distribuições mais derivadas), já que o seu arquivo ~/.bashrc padrão começa com um curto-circuito, o Ubuntu 18.04, por exemplo:

# If not running interactively, don't do anything
case $- in
    *i*) ;;
      *) return;;
esac

Isso interromperá a avaliação do arquivo se ele estiver sendo executado em um shell não interativo, que é o caso do seu script desde todos os scripts são executados em um shell não interativo e, subsequentemente, todos os arquivos source herdarão essa propriedade.

eval hack

Eu descobri um truque feio para solucionar o Ubuntu especificamente, usando eval em vez de source :

eval "$(cat ~/.bashrc | tail -n +10)"

Ele simplesmente pula as poucas primeiras linhas e avalia o resto do ~/.bashrc , então o resto é avaliado e modifica a execução atual.

Lembre-se de que é um número mágico e pode não funcionar nas versões do Ubuntu; mas pode ser uma boa solução se você estiver criando scripts para sistemas mais ou menos conhecidos.

Uma solução mais sofisticada pode envolver o uso do regex para direcionar os bits específicos que interrompem a avaliação.

Alternativa do Shebang

Outra alternativa que pode funcionar melhor em alguns cenários é forçar o script a ser executado em um shell interativo, adicionando um sinalizador no shebang :

#!/bin/bash -i

Esteja ciente de algumas coisas:

  • É uma prática melhor para usar o formulário #!/usr/bin/env bash , mas desta forma você não pode iniciar o shell com argumentos .
  • Usar o -i tem seu próprio conjunto de consequências, entre elas, os programas solicitarão a interação do usuário e isso geralmente não é destinado a scripts, por exemplo, a instalação de deb packages pode parar o script em dpkg configure prompts .
  • Inicialmente, tentei usar set -i e set +i para ativar e desativar o recurso onde precisei, mas isso não funciona .
por stefanmaric 28.05.2018 / 23:08

Tags