Um script bash de origem contém valores errados para $ BASH_SOURCE?

1

O Projeto de Documentação do Linux diz:

When a file is sourced (by typing either source filename or . filename at the command line), the lines of code in the file are executed as if they were printed at the command line. This is particularly useful with complex prompts, to allow them to be stored in files and called up by sourcing the file they are in.

Eu tenho três scripts: test.sh , test2.sh e common.sh . common.sh configura a variável $me contendo o nome base do script atual (usando ${BASH_SOURCE[0]} ). test.sh chama source em common.sh e exibe $me . test2.sh chama eval no conteúdo de common.sh e exibe $me .

==> common.sh <==
#!/bin/bash

realpath=$(realpath "${BASH_SOURCE[0]}")
me=$(basename "${realpath}")

==> test.sh <==
#!/bin/bash

source common.sh

echo "me: $me"

==> test2.sh <==
#!/bin/bash

common=$(cat common.sh)
eval "$common"

echo "me: $me"

Ao executar ./test2.sh , a saída é me: test2.sh . Isso está correto.

Ao executar ./test.sh , a saída é me: common.sh . Por que esse é o caso?

EDITAR

A resposta de Jeff Schaller está correta, pois sourcing outro script "desvia" o nome desse script para a matriz $BASH_SOURCE . Consegui alcançar o que queria ao analisar o valor last em $BASH_SOURCE . Veja abaixo:

#!/bin/bash

declare -p BASH_SOURCE
bash_source_size="${#BASH_SOURCE[*]}"
realpath=$(realpath "${BASH_SOURCE[$bash_source_size-1]}")
me=$(basename "${realpath}")
    
por magnus 08.03.2017 / 02:20

1 resposta

2

Quando test.sh chama source , o bash está explicitamente obtendo common.sh no script atual e, portanto, atualiza a variável BASH_SOURCE . Quando test2.sh executa a substituição de comando (que pode ser qualquer coisa) e subsequente eval , não há sourcing explícito acontecendo, então BASH_SOURCE não é afetado.

Instrua seus scripts de shell com

declare -p BASH_SOURCE linhas para ver a diferença:

$ ./test.sh
declare -a BASH_SOURCE='([0]="common.sh" [1]="./test.sh")'
declare -a BASH_SOURCE='([0]="./test.sh")'
me: common.sh

vs:

$ ./test2.sh
declare -a BASH_SOURCE='([0]="./test2.sh")'
declare -a BASH_SOURCE='([0]="./test2.sh")'
me: test2.sh

Em test2.sh , para todo o bash sabe, você executou um comando arbitrário, por exemplo, $(echo ls) .

    
por 08.03.2017 / 03:52