Controlando o ambiente passado ao processo filho pelo bash

2

Estou usando o x86_64 GNU / Linux com bash

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv)
{
    system("set > setc");                           // A subset of '$ set'

    return 0;
}

Eu posso ver que o arquivo setc contém um subconjunto de $ set .
Estou curioso para saber como o shell (processo pai) decide o que fornecer ao processo filho e o que não fazer?
E se eu quiser fornecer mais variáveis de ambiente para o processo filho? Como se pode controlar isso?

    
por rootkea 19.02.2015 / 16:31

3 respostas

1

O shell embutido set mostra todas as variáveis, não apenas aquelas que foram exportadas para o ambiente.

Se você quiser adicionar uma variável ao ambiente, basta fazer export variablename no seu shell.

    
por 19.02.2015 / 16:51
1

Sob o capô, o modo como as variáveis de ambiente transitam de um programa para outro é através da execve chamada do sistema , que carrega uma nova imagem de programa do disco. (Esta imagem substitui o programa atual; há outra chamada de sistema, fork , que duplica o programa atual; como system combinam fork , execve e algumas outras chamadas de sistema para iniciar um subprocesso.) Nesse nível baixo, um programa pode passar o que quiser para o programa sucessor.

No entanto, a maioria dos programas simplesmente transmite o ambiente que receberam quando começaram. Funções de biblioteca como system leem variáveis globais que são inicializadas no ambiente inicial do programa; essa variável global pode ser modificada por outras funções da biblioteca, como putenv . Se um programa não incluir código especificamente projetado para alterar o ambiente, ele transmitirá seu ambiente para seus subprocessos.

Em seu teste, você usou o comando shell set . Este comando lista variáveis do shell, que são um superconjunto de variáveis de ambiente. O shell expõe todas as suas variáveis de ambiente como variáveis da linguagem de programação shell; Além disso, você pode definir mais variáveis. O comando interno export usa o nome de uma variável de shell como um argumento e marca essa variável como exportada; variáveis marcadas como exportadas são adicionadas ao ambiente de subprocessos.

Em um shell interativo, geralmente há muitas variáveis de shell que não são exportadas. Um shell não interativo recém-iniciado tem menos. É por isso que você está vendo menos variáveis de system("set") do que você vê no seu shell interativo. Se você observasse as variáveis de ambiente (com o comando env ou export sem argumento), você encontraria o mesmo (ou talvez mais algumas, dependendo do shell).

    
por 20.02.2015 / 00:56
0

Depois de passar por man bash , temos a imagem completa. Se eu tivesse lido homem antes de postar a pergunta! BTW acima de uma resposta não parece correta enquanto outra fica aquém para esclarecer. Então:

O shell possui um ambiente de execução, que consiste em arquivos abertos herdados pelo shell na invocação, a máscara do modo de criação de arquivo, parâmetros shell herdados do pai do shell no ambiente etc. (Para mais detalhes man bash EXECUÇÃO DE COMANDO AMBIENTE) .) Os coins = declare e set quando invocados sem argumentos, cuspem os valores de todas as variáveis (no formato nome = valor) presentes no ambiente do shell. (Observe que a saída de set e declare compreende uma parte do ambiente de shells.)

Agora, quando um comando simples que não seja uma função interna ou shell deve ser executado, ele é invocado em um ambiente de execução separado que consiste em arquivos abertos do shell, máscara de modo de criação de arquivo, variáveis de shell e funções marcadas para exportação (um subconjunto de variáveis e funções no ambiente do shell) etc. Se tentarmos executar esse comando, então, como disse Gilles na resposta acima, "Se um programa não incluir código especificamente projetado para mudar o ambiente, ele transmitir seu ambiente para seus subprocessos ".

Então, quando tentamos executar o programa acima, o programa recebe um subconjunto do ambiente do shell. Então quando dizemos system ("set > setrc") o sistema () cria um processo filho (que é shell BTW) e então o shell filho executa set > setrc . Ao fazer isso, o programa transmite seu ambiente (versão reduzida do ambiente do shell pai) para o processo filho (execução do shell set ). Agora, quando set > setrc é executado, ele imprime os valores de todas as variáveis (no formato nome = valor) presentes na chamada do ambiente do shell, que é uma versão reduzida do ambiente do shell pai. É por isso que o conteúdo reduzido de setrc.

Agora Como controlar o ambiente sendo passado para um comando por Bash :

Podemos cotrolar os parâmetros e funções a serem passados pelo Bash para um comando com a ajuda de export e declare -x . ( man bash seção AMBIENTE.)

Como os outros já mencionaram export e env , apenas para esclarecer: export e env (sem argumentos) imprime o ambiente a ser passado para o subprocesso (ou comando) e NÃO o ambiente do shell enquanto set e declare mostra todas as variáveis no ambiente do shell . E é por isso que você pode fazer echo de $ VAR_NAME (qualquer variável presente em set ou declare output, apesar de NÃO estar em env ou export output).

    
por 20.02.2015 / 17:40