2011-12-30 16 views
22

sé que las variables de entorno del sistema pueden ser establecidos por la adición de entradas envariable de entorno de ajuste a nivel mundial sin necesidad de reiniciar Ubuntu

/etc/environment 

o

/etc/profile 

Pero eso requiere reiniciar el sistema o X reinicio.

¿Es posible establecer una variable de entorno en Ubuntu/Linux para que el sistema esté disponible de forma inmediata sin reiniciar el sistema operativo o desconectar al usuario?

+0

X reinicio es suficiente, ¿por qué quiere hacer un reinicio del sistema? – fge

+0

Bueno, no quiero hacer un reinicio del sistema. Ese es todo el punto. –

+1

Esto significa que no puede hacer lo que pide, entonces: _por lo menos_ tendrá que reiniciar X. No puede cambiar el entorno de un proceso en ejecución. – fge

Respuesta

14

Este programa Perl utiliza gdb para cambiar la variable de usuario en todas las conchas de bash que se están ejecutando a lo que se da como la arg programa. Para establecer una nueva variable de la llamada fiesta interno "set_if_not" podría ser utilizado

#!/usr/bin/perl 

use strict; 
use warnings; 

my @pids = qx(ps -C bash -o pid=); 
my $foo = $ARGV[0]; 
print "changing user to $foo"; 
print @pids; 

open(my $gdb, "|gdb") || die "$! gdb"; 
select($gdb); 
$|++; 
for my $pid (@pids) { 
    print "attach $pid\n"; 
    sleep 1; 
    print 'call bind_variable("USER","' . $foo . '",0)' . "\n"; 
    sleep 1; 
    print "detach\n"; 
} 

Este sólo obras con bash (sóloprobado con la versión 4.1 en Ubuntu 10.04 LTS) y no altera el medio ambiente para programas arbitrarios que ya se ejecutan. Obviamente debe ejecutarse como root.

+0

¿Por qué se necesita root para esto? – osgx

+2

@osgx, la implicación es que la variable debe cambiarse en todos los shells que se ejecutan en el sistema. Para modificar los procesos para todos los usuarios, lo más obvio es ser root – Vorsprung

+0

¡Definitivamente +1! Podría simplificarse un poco. 'ps -C bash -o pid =' podría usarse para eliminar la fila de encabezado 'PID'. Entonces '@ pid' podría usarse en lugar de' @pids [1 .. $ # pids] '. – TrueY

4

Claro export VAR=value

también puede simplemente source /etc/profile nuevo

+3

Bueno, eso afectará solo al shell en el que lo escribes (y a sus hijos), no a los otros procesos en ejecución (incluyendo X); de hecho, debes desconectarte para que todos los procesos lo tengan. – fge

+3

Esto solo configurará la variable en el proceso actual e hijos, pero no se propagará a otros procesos. – Marquez

16

La respuesta simple es: no se puede hacer esto en general.

¿Por qué no puede haber una solución general?

El "¿por qué?" necesita una explicación más detallada. En Linux, el entorno es específico del proceso. Cada entorno de proceso se almacena en un área de memoria especial asignada exclusivamente para este proceso.

Como acotación al margen: Para inspeccionar rápidamente el entorno de un proceso, echar un vistazo a /proc/<pid>/env (o tratar /proc/self/env para el medio ambiente del proceso en ejecución, tales como shell).

Cuando un proceso ("padre") se inicia otro proceso ("niño") (a través fork(2)), el medio ambiente el medio ambiente de los padres es copiado para producir el entorno del niño. No existe una asociación de estilo de herencia entre esos dos entornos a partir de entonces, están completamente separados. Entonces no hay un ambiente "global" o "maestro" que podamos cambiar, para lograr lo que quieres.

¿Por qué no simplemente cambiar el entorno por proceso de todos los procesos en ejecución? El área de memoria para el entorno se encuentra en una ubicación bien definida (básicamente justo antes de la memoria asignada para la pila), por lo que no puede extenderla fácilmente, sin dañar otras áreas críticas de la memoria del proceso.

posibles medias soluciones para casos especiales

Dicho esto, uno puede imaginar varios casos especiales donde se puede de hecho lograr lo que quiere.

  • Obviamente, si realiza cambios de "tamaño neutral", podría concebir reparar todos los entornos de todos los procesos. Por ejemplo, reemplace cada variable de entorno USER=foo (si está presente), con USER=bar. Un caso bastante especial, me temo.

  • Si realmente no necesita cambiar los entornos de todos los procesos, sino solo de una clase de conocidos, es posible que haya más enfoques creativos. Vorsprung's answer es una demostración impresionante de hacer exactamente esto con solo procesos de Bash.

Probablemente haya muchos otros casos especiales en los que existe una posible solución. Pero como se explicó anteriormente: no hay solución para el caso general.

1

Me temo que la solución aquí es frustrante: No use variables de entorno. En cambio, usa un archivo.

Así, en lugar de la configuración/etc/environment con:

SPECIAL_VAR='some/path/I/want/later/' 

y llamándolo con:

$SPECIAL_VAR 

su lugar, crear un archivo en ~/.yourvars con el contenido:

SPECIAL_VAR='some/path/I/want/later/' 

Y fuente la cosa cada vez que necesite la variable:

cd `source ~/.yourvars; echo $SPECIAL_VAR` 

¿Un truco? Quizás. Pero funciona.

-1

Ejecutar este comando en el terminal

$source /etc/profile 
Cuestiones relacionadas