Uma cópia do ambiente se propaga para subconchas, portanto, isso funciona:
$ export MY_VAR=200
$ bash
$ echo $MY_VAR
200
mas como é uma cópia, você não pode obter esse valor até o shell pai - não alterando o ambiente, pelo menos.
Parece que você realmente quer ir um passo adiante, que é criar algo que atue como uma variável global, compartilhada por shells "irmãos" iniciados separadamente dos pais - como sua nova guia no Gnome Terminal.
Principalmente, a resposta é "você não pode, porque as variáveis de ambiente não funcionam dessa maneira". No entanto, há outra resposta, que é, bem, você sempre pode hackear alguma coisa. Uma abordagem seria escrever o valor da variável em um arquivo, como ~/.myvar
, e depois incluí-lo ~/.bashrc
. Em seguida, cada novo shell começará com o valor lido desse arquivo.
Você poderia dar um passo adiante - criar ~/.myvar
no formato MYVAR=200
e depois definir PROMPT_COMMAND=source ~/.myvar
, o que faria com que o valor fosse relido toda vez que você receber um novo prompt. Ainda não é uma variável global compartilhada, mas está começando a agir assim. Porém, ele não será ativado até que um prompt volte, o que, dependendo do que você está tentando fazer, pode ser uma limitação séria.
E então, é claro, a próxima coisa a fazer é gravar automaticamente as alterações ~/.myvar
. Isso fica um pouco mais complicado, e eu vou parar neste momento, porque, na verdade, as variáveis de ambiente não foram feitas para serem um mecanismo de comunicação entre shell, e é melhor encontrar outra maneira de fazê-lo.
Esse é o seu erro aí. Você deve definir suas variáveis de ambiente
~/.profile
, que são lidas quando você efetua login. São~/.bashrc
lidas toda vez que você inicia um shell; quando você inicia o shell interno, ele substituiMY_VAR
. Se você não tivesse feito isso, sua variável de ambiente se propagaria para baixo.Para mais informações sobre
~/.bashrc
vs~/.profile
, veja minhas postagens anteriores sobre este tópico .Observe que a propagação ascendente (obter um valor modificado do subshell refletido automaticamente no shell pai) não é possível, ponto final.
fonte
Casca de peixe pode fazer isso com:
(consulte http://fishshell.com/docs/current/commands.html#set )
Para executar um comando fish de outro shell, você pode executar
fish -c
, por exemplo:fonte
Não use variáveis de ambiente. Use arquivos.
Para impedir que os processos se interponham ao atualizar / ler o arquivo, use arquivos de bloqueio e pequenos scripts de atualização de front-end, cujo objetivo é apenas atualizar um arquivo com $ 1, se não estiver bloqueado. Os arquivos de bloqueio são implementados verificando basicamente se existe um arquivo específico (/var/run/yourscript.lck) e, se existir, aguarde o arquivo desaparecer por um tempo e falhe se não existir. Além disso, você deve excluir o arquivo de bloqueio ao concluir a atualização do arquivo.
Esteja preparado para lidar com uma situação em que um script não pode atualizar um arquivo porque o arquivo está ocupado.
fonte
mkdir
funciona como um teste e criação atômico.flock(2)
ln -s dummy lockfile
(mesmo se quebrado) também pode funcionar, pois falhará se o link simbólico já existir. Gostaria de saber uma maneira de testar se isso é realmente 100% seguro.Quando acabei de pesquisar esta questão, eu estava tentando resolver o problema de atualizar o estado (ou seja, variáveis de shell) de fora das subcascas. Para que se possa atribuir variáveis, digamos, dentro de um pipeline - e a atribuição seja visível de forma transparente para o pai.
Obviamente, isso não é possível de uma maneira simples, porque partes individuais de um pipeline são executadas em subcascas, que são
fork
editadas a partir do shell pai e, portanto, possuem memória que é a visão de cópia na gravação na memória do pai. No entanto, eu supunha que uma solução fina e transparente fosse possível com base no tipo de IPCs de " memória compartilhada " .E eu até encontrei uma implementação exatamente desse design ... mas é em Perl.
Adicionando esta resposta de qualquer maneira como uma possível solução.
fonte