Observação: as variáveis de ambiente definidas usando o utilitário "read" do sistema operacional, que contêm valores somente numéricos, não são acessíveis na os.environ[]
estrutura do Python ou pela estrutura do nó process.env
, mas SÃO acessíveis ao bash.
O comportamento esperado é que todas as variáveis de ambiente sejam igualmente acessíveis a partir dos aplicativos, independentemente de como foram criadas.
As mesmas variáveis, se definidas usando bash usando export N=12345
sintaxe, são acessíveis. Parece que a variável criada usando o comando read não é criada igual a outras variáveis de alguma forma que está perturbando a lógica do nó/Python de analisar essas variáveis.
As mesmas variáveis que não são acessíveis do node/Python são prontamente acessíveis na linha de comando bash, conforme mostrado abaixo nas instruções echo.
O comando read define uma variável de ambiente com base na entrada de chave. É uma maneira conveniente de inserir um segredo em uma variável sem deixar um registro .bash_history desse segredo.
Reproduzido em:
- OSX 10.14.6 ("Mojave") Python 2.7, Python 3.6, nó 10.16.3 Linux
- Kernel 3.10 CentOS 64 bits, Python2.7.5
Amostra:
Use read
e solicite ao usuário que insira um valor para a variável de ambiente denominada L.
~ $ read L
12345
~ $ python2
Python 2.7.16 (default, Apr 12 2019, 15:32:40)
[GCC 4.2.1 Compatible Apple LLVM 10.0.1 (clang-1001.0.46.3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> os.environ["L"]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/Cellar/python@2/2.7.16/Frameworks/Python.framework/Versions/2.7/lib/python2.7/UserDict.py", line 40, in __getitem__
raise KeyError(key)
KeyError: 'L'
>>>
~ $ python3
Python 3.7.3 (default, Mar 27 2019, 09:23:15)
[Clang 10.0.1 (clang-1001.0.46.3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> os.environ["L"]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/Cellar/python/3.7.3/Frameworks/Python.framework/Versions/3.7/lib/python3.7/os.py", line 678, in __getitem__
raise KeyError(key) from None
KeyError: 'L'
~ $ echo $L
12345
Curiosamente, se uma variável numérica for definida por outros meios além do comando read, elas estarão acessíveis em Python e node.
>>> os.environ["HISTSIZE"]
'12345678'
No shell, você não está trabalhando com variáveis de ambiente – você está trabalhando com variáveis de shell . O shell apenas começa com uma cópia de seu ambiente inicial, mas mantém seu próprio namespace variável.
As variáveis de shell só serão copiadas de volta para o ambiente se tiverem o sinalizador 'exportar' . Variáveis novas não são exportadas por padrão – não importa como elas foram geradas, você ainda precisa usar o
export
comando para definir o sinalizador correto nelas:Observe novamente que isso não é específico para
read
. Você pode ver a mesma falha se simplesmente definir uma variável sem usarexport
:No bash, você pode usar
declare -p VAR
para verificar se essa variável está sinalizada para exportação para o ambiente (ela terá a-x
opção em caso afirmativo).(A saída é válida como entrada - por exemplo, se você realmente executar
declare -x
, isso é equivalente aexport
.)Notas diversas:
O ambiente pode conter apenas valores de string, mas as variáveis do shell não se limitam apenas a isso – por exemplo, a maioria dos shells tem arrays/listas e dicts.
Os shells geralmente têm variáveis que não se deseja exportar. Por exemplo, $LINES e $COLUMNS são dinâmicos dentro do próprio shell, mas exportá-los permitiria apenas que os programas vissem um valor estático e isso causaria problemas.