set + a não desanima o sinalizador -a

4

No Mac 10.11.6, usando o GNU bash, versão 3.2.57 (1) -release (x86_64-apple-darwin15), o comando set +a parece não funcionar:

script.py

#!/usr/bin/python
import os
print("VAR0 is:", os.environ.get("VAR0")

Comandos:

$ VAR0=abc
$ ./script.py
('VAR0 is:', None)   # expected
$ set -a
$ VAR0=abc
$ ./script.py
('VAR0 is:', 'abc')   # expected, VAR0 has been exported to the environment and script.py has access to it
$ set +a
$ VAR0=def
$ ./script.py
('VAR0 is:', 'def')   # <= unexpected
    
por AJP 22.06.2017 / 19:23

3 respostas

3
Remova: Sim, set +a unsets set -a , mas as variáveis não são exportadas por causa disso. Cada variável precisa ser exportada ou não definida.

A opção allexport (Igual a set -a ) permite a exportação automática de variáveis new e changed . Variáveis que existem antes de ativar a opção set -a não serão exportadas.

Dois pontos antes de testar:

  1. A condição de set -a pode ser impressa com shopt -po allexport .
    E pode ser alterado com shopt -os allexport e shopt -ou allexport .

    $ shopt -po allexport
    set +o allexport
    
    $ set -a
    $ shopt -po allexport
    set -o allexport
    
    $ set +a
    $ shopt -po allexport
    set +o allexport
    
  2. A maneira do shell de testar variáveis de ambiente é examinar a saída do comando environment , na verdade, para grep it

    $ env | grep PATH
    PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
    

Não há necessidade de um programa externo do python (que precisa ser compilado na primeira chamada). Você ainda pode usá-lo se isso te faz feliz, mas não há necessidade real disso.

Se a opção não estiver definida ( set +a ). Uma nova variável não será exportada.

$ unset VAR0
$ VAR0=abc
$ env | grep VAR0
                      # nothing is printed.

Ou, se você ainda quiser o seu programa:

$ ./envtest.py
VAR0 is: None

Se a opção -a for alterada, o var não será exportado até ser alterado:

$ set -a
$ shopt -po allexport
set -o allexport
$ env | grep VAR0
$ ./envtest.py
VAR0 is: None

Se a variável mudar:

$ VAR0=bcd
$ env | grep VAR0
VAR0=bcd
$ ./envtest.py
VAR0 is: bcd

Mas a variável permanecerá no ambiente se o set +a for aplicado:

$ set +a
$ env | grep VAR0
VAR0=bcd
$ ./envtest.py
VAR0 is: bcd

Mesmo que o var seja alterado, ainda faz parte do ambiente:

$ VAR0=xyz
$ env | grep VAR0
VAR0=xyz
$ ./envtest.py
VAR0 is: xyz

Até que ele não seja exportado (remova o atributo de exportação):

$ declare +x VAR0

Ou é simplesmente unset

$ env | grep VAR0
VAR0=xyz
$ unset VAR0
$ env | grep VAR0

Não, atribuir um valor vazio não é o mesmo:

$ VAR0=''
$ env | grep VAR0
VAR0=

Qual seu programa não mostra isso claramente:

$ ./envtest.py
VAR0 is: 
    
por 23.06.2017 / 04:38
4

Você entendeu mal o que o set -a faz. Se uma variável é exportada, as alterações nessa variável são sempre refletidas no ambiente. (Isso nem sempre foi verdadeiro para as implementações históricas de sh , mas é verdadeiro em todos os shells modernos compatíveis com POSIX (-ish).) A opção -a força uma variável a ser exportada mesmo se não for antes: por padrão, uma atribuição cria uma variável de shell, mas quando -a está em vigor, a atribuição faz com que a variável seja exportada mesmo que ainda não esteja.

set +a anula a opção -a . Alterar o valor de uma variável exportada afeta o ambiente se -a está em vigor ou não.

    
por 23.06.2017 / 04:28
2

Isso ocorre porque a atribuição à variável de shell local agora está afetando a variável de ambiente. Se você primeiro desmarcar a variável, as atribuições futuras só funcionarão na variável shell local como antes:

$ unset VAR0
$ VAR0=def
$ ./script.py
('VAR0 is:', 'None')
    
por 22.06.2017 / 19:26