Establecer variables de entorno en C

¿Hay alguna manera de establecer variables de entorno en Linux usando C?

Intenté setenv() y putenv() , pero no parecen funcionar para mí.

Voy a adivinar aquí, pero la razón normal por la que estas funciones parecen no funcionar no es porque no funcionen, sino porque el usuario realmente no entiende cómo funcionan las variables de entorno. Por ejemplo, si tengo este progtwig:

 int main(int argc, char **argv) { putenv("SomeVariable=SomeValue"); return 0; } 

Y luego lo ejecuto desde el shell, no modificará el entorno del shell – no hay forma de que un proceso hijo haga eso. Es por eso que los comandos del shell que modifican el entorno son comandos integrados, y por qué necesita generar un script que contenga las configuraciones variables que desea agregar a su caparazón, en lugar de simplemente ejecutarlo.

Cualquier progtwig Unix se ejecuta en un proceso separado del proceso que lo inicia; este es un proceso ‘infantil’.

Cuando se inicia un progtwig, ya sea en la línea de comandos o de otra forma, el sistema crea un nuevo proceso que es (más o menos) una copia del proceso principal. Esa copia incluye las variables de entorno en el proceso padre, y este es el mecanismo por el cual el proceso hijo ‘hereda’ las variables de entorno de su elemento primario. (Esto es todo lo que otras respuestas han dicho)

Es decir, un proceso solo establece sus propias variables de entorno.

Otros han mencionado el origen de un script de shell, como una forma de establecer variables de entorno en el proceso actual, pero si necesita establecer variables en el proceso actual (shell) mediante progtwigción, entonces hay una manera ligeramente indirecta de que sea posible.

Considera esto:

 % cat envs.c #include  int main(int argc, char**argv) { int i; for (i=1; i 

La evaluación incorporada evalúa su argumento como si ese argumento se escribiera en el indicador del intérprete de comandos. Este es un ejemplo de estilo sh; la variante de estilo csh se deja como un ejercicio!

La variable de entorno establecida por setenv () / putenv () se establecerá para el proceso que ejecutó estas funciones y será heredada por los procesos iniciados por ella. Sin embargo, no se emitirá en el shell que ejecutó su progtwig.

¿Por qué no funciona mi envoltorio alrededor de setenv ()?

El bloque de entorno es process-local y se copia en procesos secundarios. Por lo tanto, si cambia las variables, el nuevo valor solo afecta su proceso y los procesos secundarios se generan después del cambio. Seguramente no cambiará el proyectil desde el que se lanzó.

Lo obtuve de mi libro ” Progtwigción avanzada en el entorno UNIX “ .

El entorno enumera la matriz de punteros a las cadenas de nombre = valor real, y las cadenas de entorno normalmente se almacenan en la parte superior del espacio de memoria de un proceso, encima de la stack.

Eliminar una cadena es simple; simplemente buscamos el puntero en la lista de entornos y movemos todos los punteros subsecuentes hacia abajo uno. Pero agregar una cadena o modificar una cadena existente es más difícil. El espacio en la parte superior de la stack no se puede expandir, porque a menudo está en la parte superior del espacio de direcciones del proceso y, por lo tanto, no puede expandirse hacia arriba; no se puede expandir hacia abajo, porque no se pueden mover todos los marcos de stack debajo.

  1. Si estamos modificando un nombre existente:

    a. Si el tamaño del nuevo valor es menor o igual que el tamaño del valor existente, podemos simplemente copiar la nueva cadena sobre la cadena anterior.

    segundo. Sin embargo, si el tamaño del nuevo valor es mayor que el anterior, debemos malloc para obtener espacio para la nueva cadena, copiar la nueva cadena en esta área y luego reemplazar el puntero anterior en la lista de entorno por el nombre con el puntero a esta área asignada.

  2. Si estamos agregando un nuevo nombre, es más complicado. En primer lugar, debemos llamar a malloc para asignar espacio para la cadena name = value y copiar la cadena a esta área.

    a. Entonces, si es la primera vez que agregamos un nombre nuevo, debemos llamar a malloc para obtener espacio para una nueva lista de punteros. Copiamos la lista de entorno anterior a esta nueva área y almacenamos un puntero a la cadena name = value al final de esta lista de punteros. También almacenamos un puntero nulo al final de esta lista, por supuesto. Finalmente, establecemos el entorno para apuntar a esta nueva lista de punteros. si la lista del entorno original estaba contenida encima de la parte superior de la stack, como es común, entonces hemos movido esta lista de punteros al montón. Pero la mayoría de los punteros en esta lista aún apuntan a nombre = cadenas de valor por encima de la parte superior de la stack.

    segundo. Si esta no es la primera vez que agregamos cadenas nuevas a la lista de entornos, entonces sabemos que ya hemos asignado espacio para la lista en el montón, así que simplemente llamamos a realloc para asignar espacio para un puntero más. El puntero a la nueva cadena name = value se almacena al final de la lista (en la parte superior del puntero nulo anterior), seguido de un puntero nulo.

Todo lo mejor.