2008-10-15 10 views
70

En Unix, ¿hay alguna forma en que un proceso pueda cambiar las variables de entorno de otra persona (suponiendo que todas estén siendo ejecutadas por el mismo usuario)? Una solución general sería la mejor, pero si no, ¿qué pasa con el caso específico donde uno es hijo de otro?¿Hay alguna manera de cambiar las variables de entorno de otro proceso en Unix?

Editar: ¿Qué tal vía gdb?

+0

Esto me parece más que feo. ¿Cuál es el problema real que quieres resolver? – Jens

+0

Ejemplo: Me gustaría definir una variable de entorno para que cada nueva aplicación, lanzada por la interfaz de usuario, pueda obtenerla. No conozco ningún método excepto la definición de las variables en uno de los scripts de inicio y RE-LOGIN. Sin embargo, me gustaría no volver a iniciar sesión, sino simplemente definir las variables en la sesión actual para que las nuevas aplicaciones la obtengan, sin necesidad de cerrar la sesión de la IU. –

Respuesta

104

Via GDB:

(gdb) attach process_id 

(gdb) call putenv ("env_var_name=env_var_value") 

(gdb) detach 

Este es un truco desagradable y sólo debe hacerse en el contexto de un escenario de depuración, por supuesto.

+4

Esto parece implicar que puede cambiar el entorno de un proceso si se conecta al proceso como lo hace GDB, y luego se desconecta. Parece que sería posible escribir un programa que solo haga esto. – grieve

+3

"Parece que sería posible escribir un programa que solo haga esto" De hecho ... lo es. –

+4

+1 ¡En realidad responde la pregunta! –

1

Si tu UNIX admite el sistema de archivos/proc, entonces es trivial LEER el env, puedes leer el entorno, la línea de comandos y muchos otros atributos de cualquier proceso que poseas de esa manera. Cambiándolo ... Bueno, puedo pensar en una forma, pero es una MALA idea.

El caso más general ... No lo sé, pero dudo que haya una respuesta portátil.

(Editado: mi primera respuesta asumió la OP quería leer el env, no cambiarlo)

+0

Ooops, editó mi respuesta: suponía que quería leer el env, no cambiarlo. –

+1

No me dejes colgando. ¿Cuál es tu mala idea? – raldi

+0

En Linux, creo que PODRÍAS poder abrir/proc//mem read-write para otro proceso que poseas ... No estoy seguro, sin embargo. Intentar, y realmente jugar con el medio ambiente, DEFINITIVAMENTE sería una mala idea. Así que no estoy sugiriendo que lo intentes ... –

7

Citando Jerry Peek:

You can't teach an old dog new tricks.

La única cosa que puede hacer es cambiar la variable de entorno del proceso hijo antes de comenzando: obtiene la copia del entorno principal, lo siento.

Ver http://www.unix.com.ua/orelly/unix/upt/ch06_02.htm para más detalles.

Solo un comentario sobre la respuesta sobre el uso de/proc. En linux/proc es compatible, pero no funciona, usted no puede cambiar el archivo /proc/${pid}/environ, incluso si usted es root: es absolutamente de solo lectura.

+0

Lo cual aún deja la pregunta: ¿dónde se almacenan realmente los valores de env var? ¿Eso lo hace el kernel? ¿O el shell almacena los valores y/proc//environ los obtiene de allí? – oliver

+0

Este es un detalle de implementación, y podría ser una buena pregunta (por separado). Creo que cada UNIX usa su propia forma de almacenamiento, pero todos comparten el comportamiento descrito anteriormente, que es parte de las especificaciones. – Davide

2

No es lo que yo sé. Realmente intentas comunicar de un proceso a otro que requiere uno de los métodos de IPC (memoria compartida, semáforos, tomas de corriente, etc.). Una vez que haya recibido los datos por uno de estos métodos, podrá establecer variables de entorno o realizar otras acciones más directamente.

2

O conseguir su proceso de actualización de un archivo de configuración para el nuevo proceso y luego o bien:

  • realizar una matanza HUP en el nuevo proceso de volver a leer el archivo de configuración actualizada o
  • tienen el proceso de revise el archivo de configuración para ver las actualizaciones de vez en cuando. Si se encuentran cambios, vuelva a leer el archivo de configuración.

HTH.

aplausos,

Rob

5

que podría pensar en la forma bastante artificiales para hacer eso, y no van a trabajar para procesos arbitrarios.

Supongamos que usted escribe su propia biblioteca compartida que implementa 'char * getenv'. Luego, configura el env de 'LD_PRELOAD' o 'LD_LIBRARY_PATH'. vars para que ambos procesos se ejecuten con la biblioteca compartida precargada.

De esta manera, esencialmente tendrá un control sobre el código de la función 'getenv'. Entonces, podrías hacer todo tipo de trucos desagradables. Su 'getenv' podría consultar el archivo de configuración externo o el segmento SHM para valores alternativos de env vars.O puede hacer una búsqueda regular/reemplazar en los valores solicitados. O ...

No puedo pensar en una forma fácil de hacerlo para procesos en ejecución arbitrarios (incluso si eres root), salvo para reescribir el enlazador dinámico (ld-linux.so).

13

Sustancialmente, no. Si tenía privilegios suficientes (raíz, o menos) y hurgó en/dev/kmem (memoria del kernel), e hizo cambios en el entorno del proceso, y si el proceso realmente re-referenciaba la variable de entorno después (es decir, el proceso aún no había tomado una copia del env var y no estaba usando solo esa copia), entonces tal vez, si era afortunado e inteligente, y el viento soplaba en la dirección correcta, y la fase de la luna era correcta, tal vez, puedes lograr algo

+1

No recibí la respuesta. –

+0

@kilaka: La palabra clave es la segunda - ** No **. El resto de la respuesta dice que si tiene privilegios de administrador o está ejecutando un depurador, entonces quizás pueda hacerlo, pero para todos los propósitos prácticos, la respuesta es ** No **. –

+2

¿Qué hay de gdb? –

19

Probablemente pueda hacerlo técnicamente (ver otras respuestas), pero puede que no lo ayude.

La mayoría de los programas esperarán que los archivos no se puedan cambiar desde el exterior después del inicio, por lo tanto, la mayoría probablemente solo leerán los vars que les interesan al inicio e inicializarán en función de eso. Entonces, cambiarlos después no marcará la diferencia, ya que el programa nunca los volverá a leer.

Si publicó esto como un problema concreto, probablemente debería tener un enfoque diferente. Si fue solo por curiosidad: Buena pregunta :-).

1

No es una respuesta directa, pero ... Raymond Chen had a [Windows-based] rationale around this only the other day: -

... Although there are certainly unsupported ways of doing it or ways that work with the assistance of a debugger, there’s nothing that is supported for programmatic access to another process’s command line, at least nothing provided by the kernel. ...

That there isn’t is a consequence of the principle of not keeping track of information which you don’t need. The kernel has no need to obtain the command line of another process. It takes the command line passed to the CreateProcess function and copies it into the address space of the process being launched, in a location where the GetCommandLine function can retrieve it. Once the process can access its own command line, the kernel’s responsibilities are done.

Since the command line is copied into the process’s address space, the process might even write to the memory that holds the command line and modify it. If that happens, then the original command line is lost forever; the only known copy got overwritten.

En otras palabras, cualquiera de dichas instalaciones kernel habría

  • difíciles de aplicar
  • potencialmente un problema de seguridad

Sin embargo, la razón más probable es simplemente que hay casos de uso limitado para tales instalaciones.

1

UNIX está lleno de comunicación entre procesos. Verifica si tu instancia objetivo tiene algo. Dbus se está convirtiendo en un estándar en IPC "de escritorio".

Cambio las variables de entorno dentro de Awesome window manager usando awesome-client con es un "emisor" de Dbus del código lua.

Cuestiones relacionadas