Referindo-se a um arquivo relativo à execução do script


94

Em um script bash que estou escrevendo, uso sourcepara incluir a variável definida em um arquivo de configuração. O script a ser executado é act.sh, enquanto o script a ser sourced é act.conf.sh, então act.sheu tenho:

source act.conf.sh

No entanto, isso só funciona quando executado act.shno diretório que o contém, uma vez act.conf.shque se refere ao arquivo colocado sob o diretório de trabalho. Existe uma solução para fazer com que se refira ao arquivo relativo ao script em execução sem invocar cd? Obrigado.

Respostas:


116

Consulte: Entrada nº 28 da FAQ do BASH: "Como determino a localização do meu script? Quero ler alguns arquivos de configuração do mesmo lugar."

Qualquer solução não vai funcionar 100% do tempo:

É importante perceber que no caso geral, esse problema não tem solução. Qualquer abordagem da qual você já deve ter ouvido falar, e qualquer abordagem que será detalhada a seguir, tem falhas e só funcionará em casos específicos. Em primeiro lugar, tente evitar o problema totalmente, não dependendo da localização do seu script!

Se você precisar escrever uma ferramenta muito reutilizável, usar o caminho correto como parâmetro para o seu script será o método mais confiável .

Supondo que seu script será executado apenas a partir de determinados shells, e apenas com um pouco de flexibilidade necessária, você provavelmente pode relaxar um pouco dessa paranóia. Ainda é bom olhar para as suas opções. Existem padrões comuns que as pessoas usam que são particularmente problemáticos.

Em particular, o FAQ recomenda evitar a $0variável muito comumente usada :

Nada do que lê $0jamais será à prova de balas, porque em $0si mesmo não é confiável.

Como alternativa, você pode usar $BASH_SOURCE. Algo assim:

source "${BASH_SOURCE%/*}/act.conf.sh"

Existem algumas ressalvas para essa solução também. Confira a página de perguntas frequentes para ver as compensações entre as diferentes soluções. Eles parecem ser recomendados cdem combinação com $BASH_SOURCEcasos em que funcionará para você, pois você obterá uma condição de erro útil quando ele não se expandir adequadamente.


1
Obrigado, eu usaria readlink. Não foi possível determinar as palavras-chave a serem pesquisadas, então postei a pergunta aqui ...
Ryan Li

9
Você pode inserir as informações relevantes na resposta caso o bash faq esteja desativado?
Merlyn Morgan-Graham

3
Link recomenda :,cd "${BASH_SOURCE%/*}" || exit ou read somevar < "${BASH_SOURCE%/*}/etc/somefile"Link Desencoraja fortemente $0 "Nada que leia $ 0 será à prova de balas, porque $ 0 em si não é confiável."
ThorSummoner

10
O que faz% / * após BASH_SOURCE e como?
Silicomancer



5

Experimente o seguinte:

source ${BASH_SOURCE[0]/%act.sh/act.conf.sh}
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.