Script BASH para definir variáveis ​​de ambiente que não funcionam

137

Eu escrevi o script a seguir para definir algumas variáveis ​​de ambiente quando necessário.

#!/bin/sh
export BASE=/home/develop/trees
echo $BASE
export PATH=$PATH:$BASE
echo $PATH

Abaixo do comando e dos resultados que posso ver no meu terminal: o script é executado, mas as variáveis ​​não são definidas no final.

~$: ./script.sh
/home/develop/trees
/bin:......:/home/develop/trees
~$: echo $BASE

~$: 

O que há de errado? Desde já, obrigado. Mirko

MirkoZa
fonte

Respostas:

194

exportexporta a atribuição de variável para processos filho do shell no qual o exportcomando foi executado. Seu ambiente de linha de comando é o pai do shell do script, portanto, ele não vê a atribuição de variável.

Você pode usar o comando .(ou source) bash para executar os comandos de script no ambiente atual do shell e alcançar o que deseja, por exemplo

source ./script.sh
echo "$BASE"

Vai produzir

/home/develop/trees

O sourcecomando, geralmente visto em scripts, é um sinônimo bash para ., que faz parte do padrão POSIX (portanto, .está disponível no dash, por exemplo, mas sourcenão é).

. ./script.sh     # identical to "source ./script.sh"

( . script.shE source script.shprocurará primeiro por script.shnos PATH, por isso é mais seguro especificar o caminho para script.sh.)

muru
fonte
29
Você não precisa exportpassar variáveis ​​para os subshells, um subshell é uma cópia do seu shell atual, incluindo variáveis ​​e funções etc. As variáveis ​​exportadas são copiadas para novos processos gerados no shell, independentemente de esse processo ser outro shell ou não. Em segundo lugar, .é o comando POSIX para fornecimento. O Bash é adicionado sourcecomo um sinônimo mais legível, mas você não pode confiar que ele esteja disponível no sh. Por fim, em . ./scriptvez de . scriptse você quiser evitar surpresas. mywiki.wooledge.org/BashFAQ/060
geirha
Observe que, se você originar um script E usar pipe, o ambiente de origem não estará disponível para o pai. por exemplo, 'source setit.sh' está bom. 'fonte setit.sh | tee setit.log' não está bem. Surpreendente. Não é intuitivo.
gaoithe
10

Quando você executa um script, ele é executado em um subshell. As variáveis ​​são válidas apenas dentro do contexto desse subshell. Defina-os no seu .bashrcou .profilee leia as variáveis ​​e subshells . A exportinstrução trabalha com hierarquia (shell atual e todos os seus subshells), não como no seu exemplo.

Como alternativa (se você realmente deseja que o script efetue o ambiente do seu shell atual), execute-o como:

. ./script.sh

Isso faz com que ele seja executado no seu shell atual, mas também não passa variáveis ​​na hierarquia.

confundir
fonte
5

Muitas vezes, quero definir uma variável de ambiente sem problemas.

Aqui está o que eu adiciono ao meu .bashrc para implementar essa conveniência.

defect() {
    if [ $1 ] && [ -z $2 ]
    then
        eval 'export DEFECT=$1'
        return 0
    else
        echo 'Usage: defect {number}'
        return 1
    fi
}
jlettvin
fonte
-1

Você pode tentar algo como isto

CURRENT_DIR=`pwd`
echo "SOME_PATH is pointing to ${CURRENT_DIR}"
#Export SOME_PATH for current working directory
export SOME_PATH=${CURRENT_DIR}
silentsudo
fonte