Existe uma maneira de alterar as variables ​​de ambiente de outro processo no Unix?

No Unix, existe alguma maneira de um processo poder alterar as variables ​​de ambiente de outro (assumindo que todas estão sendo executadas pelo mesmo usuário)? Uma solução geral seria melhor, mas se não, o que acontece com o caso específico em que um é filho do outro?

Edit: Como sobre via gdb?

Via gdb:

(gdb) attach process_id (gdb) call putenv ("env_var_name=env_var_value") (gdb) detach 

Este é um truque bastante desagradável e só deve ser feito no contexto de um cenário de debugging, é claro.

Você provavelmente pode fazer isso tecnicamente (veja outras respostas), mas isso pode não ajudar você.

A maioria dos programas espera que o env vars não possa ser alterado do lado de fora após a boot, portanto, a maioria provavelmente lerá apenas os vars em que eles estão interessados ​​na boot e inicializará com base nisso. Então, alterá-los depois não fará diferença, uma vez que o programa nunca os relerá.

Se você postou isso como um problema concreto, provavelmente deveria adotar uma abordagem diferente. Se foi apenas por curiosidade: boa pergunta :-).

Substancialmente, não. Se você tivesse privilégios suficientes (root, ou próximo) e passasse por / dev / kmem (memory do kernel), e fizesse alterações no ambiente do processo, e se o processo realmente referenciasse novamente a variável de ambiente (isto é, o processo já não tinha tirado uma cópia do env var e não estava usando apenas aquela cópia), então talvez, se você tivesse sorte e fosse inteligente, e o vento estivesse soprando na direção certa, e a fase da lua estivesse correta, talvez, você pode conseguir alguma coisa.

Citando Jerry Peek:

Você não pode ensinar truques novos a um cachorro velho.

A única coisa que você pode fazer é alterar a variável de ambiente do processo filho antes de iniciá-lo: obtém a cópia do ambiente pai, desculpe.

Veja http://www.unix.com.ua/orelly/unix/upt/ch06_02.htm para detalhes.

Apenas um comentário sobre a resposta sobre o uso de / proc. Sob linux / proc é suportado mas, não funciona, você não pode mudar o arquivo /proc/${pid}/environ , mesmo se você for root: é absolutamente somente leitura.

Eu poderia pensar na maneira mais artificial de fazer isso, e isso não funcionará para processos arbitrários.

Suponha que você escreva sua própria biblioteca compartilhada que implementa ‘char * getenv’. Então, você configura ‘LD_PRELOAD’ ou ‘LD_LIBRARY_PATH’ env. vars para que ambos os processos sejam executados com sua biblioteca compartilhada pré-carregada.

Desta forma, você essencialmente terá um controle sobre o código da function ‘getenv’. Então, você poderia fazer todos os tipos de truques desagradáveis. Seu ‘getenv’ pode consultar um arquivo de configuração externo ou um segmento SHM para valores alternativos de env vars. Ou você pode fazer uma pesquisa / substituição regular nos valores solicitados. Ou …

Não consigo pensar em uma maneira fácil de fazer isso para processos de execução arbitrários (mesmo se você for root), não reescrevendo o linker dynamic (ld-linux.so).

Não tão longe quanto o que sei. Realmente você está tentando se comunicar de um processo para outro, o que requer um dos methods IPC (memory compartilhada, semáforos, sockets, etc.). Tendo recebido dados por um desses methods, você poderia definir variables ​​de ambiente ou executar outras ações mais diretamente.

Ou obtenha seu processo para atualizar um arquivo de configuração para o novo processo e, em seguida:

  • executar um kill -HUP no novo processo para reler o arquivo de configuração atualizado, ou
  • ter o processo verificar o arquivo de configuração para atualizações de vez em quando. Se forem encontradas alterações, releia o arquivo de configuração.

HTH.

Felicidades,

Roubar

Se o seu unix suporta o sistema de arquivos / proc, então é trivial ler o env – você pode ler o ambiente, a linha de comando e muitos outros atributos de qualquer processo que você possua dessa maneira. Mudando … Bem, eu posso pensar em um jeito, mas é uma má ideia.

O caso mais geral … Eu não sei, mas duvido que exista uma resposta portátil.

(Editado: minha resposta original assumiu que o OP queria ler o env, não alterá-lo)

O UNIX está cheio de comunicação entre processos. Verifique se sua instância de destino tem algum. O Dbus está se tornando um padrão no IPC “desktop”.

Eu mudo variables ​​de ambiente dentro do gerenciador de janelas Awesome usando awesome-client com é um “remetente” Dbus do código lua.

Não é uma resposta direta, mas … Raymond Chen teve um raciocínio [baseado no Windows] sobre isso apenas no outro dia : –

… Embora certamente haja maneiras não suportadas de fazer isso ou formas que funcionam com a ajuda de um depurador, não há nada que seja suportado para access programático à linha de comando de outro processo, pelo menos nada fornecido pelo kernel. …

O que não existe é uma consequência do princípio de não acompanhar as informações de que você não precisa. O kernel não precisa obter a linha de comando de outro processo. Ele leva a linha de comando passada para a function CreateProcess e copia para o espaço de endereço do processo que está sendo iniciado, em um local onde a function GetCommandLine pode recuperá-lo. Uma vez que o processo pode acessar sua própria linha de comando, as responsabilidades do kernel são feitas.

Como a linha de comando é copiada no espaço de endereço do processo, o processo pode até gravar na memory que contém a linha de comando e modificá-la. Se isso acontecer, a linha de comando original será perdida para sempre; a única cópia conhecida foi substituída.

Em outras palavras, qualquer instalação do kernel seria

  • difícil de implementar
  • potencialmente uma preocupação de segurança

No entanto, o motivo mais provável é simplesmente que há casos de uso limitados para tal instalação.