permanently - ¿Por qué las variables ambientales establecidas en Python no pueden persistir?
set environment variable linux permanently (6)
Como respondió Benson, pero el mejor truco es crear una función bash simple para preservar los argumentos:
upsert-env-var (){ eval $(python upsert_env_var.py $*); }
Puedes hacer lo que quieras en tu script python con los argumentos. Para agregar una variable simplemente use algo como:
var = sys.argv[1]
val = sys.argv[2]
if os.environ.get(var, None):
print "export %s=%s:%s" % (var, val, os.environ[var])
else:
print "export %s=%s" % (var, val)
Uso:
upsert-env-var VAR VAL
Tenía la esperanza de escribir un script de Python para crear algunas variables ambientales apropiadas ejecutando el script en cualquier directorio en el que esté ejecutando algún código de simulación, y he leído que no puedo escribir un script para hacer que estos archivos persistan en el terminal mac os. Entonces dos cosas:
¿Es esto cierto?
y
Parece que sería una cosa útil que hacer; ¿Por qué no es posible en general?
Generalmente no es posible. El nuevo proceso creado para python no puede afectar el entorno de su proceso principal. El padre tampoco puede afectar al niño, pero el padre puede configurar el entorno del niño como parte de la creación del nuevo proceso.
Tal vez pueda configurarlos en .bashrc
, .profile
o el .profile
"ejecuta al iniciar sesión" o "ejecuta en cada nueva sesión de terminal" en MacOS.
También puede hacer que Python inicie el programa de simulación con el entorno deseado. (use el parámetro env
para subprocess.Popen ( http://docs.python.org/library/subprocess.html ))
import subprocess, os
os.chdir(''/home/you/desired/directory'')
subprocess.Popen([''desired_program_cmd'', ''args'', ...], env=dict(SOMEVAR=''a_value'') )
O podría hacer que Python escriba un script de shell como este en un archivo con una extensión .sh
:
export SOMEVAR=a_value
cd /home/you/desired/directory
./desired_program_cmd
y luego chmod +x
it y ejecutarlo desde cualquier lugar.
Lo que me gusta hacer es usar / usr / bin / env en un script de shell para "ajustar" mi línea de comando cuando me encuentro en situaciones similares:
#!/bin/bash
/usr/bin/env NAME1="VALUE1" NAME2="VALUE2" ${*}
Así que llamemos a este script "myappenv". Lo puse en mi directorio $ HOME / bin que tengo en mi $ PATH.
Ahora puedo invocar cualquier comando usando ese entorno simplemente anteponiendo "myappenv" como tal:
myappenv dosometask -xyz
Otras soluciones publicadas también funcionan, pero esta es mi preferencia personal. Una ventaja es que el entorno es transitorio, por lo que si estoy trabajando en el shell solo el comando que invoco se ve afectado por el entorno modificado.
Versión modificada basada en nuevos comentarios
#!/bin/bash
/usr/bin/env G4WORKDIR=$PWD ${*}
Podrías envolver todo esto en un alias también. Prefiero el enfoque del script de envoltura, ya que también tengo la preparación de otro entorno, lo que me facilita mantenerlo.
No puedes hacerlo desde Python, pero algunos trucos de bash inteligentes pueden hacer algo similar. El razonamiento básico es este: las variables de entorno existen en un espacio de memoria por proceso. Cuando se crea un nuevo proceso con fork () hereda las variables de entorno de sus padres. Cuando configura una variable de entorno en su shell (por ejemplo, bash) de esta manera:
export VAR="foo"
Lo que estás haciendo es decirle a bash que configure la variable VAR en su espacio de proceso para "foo". Cuando ejecuta un programa, bash usa fork () y luego exec () para ejecutar el programa, por lo que todo lo que ejecuta desde bash hereda las variables de entorno bash.
Ahora, supongamos que desea crear un comando bash que establezca alguna variable de entorno DATA con contenido de un archivo en su directorio actual llamado ".data". Primero, necesita tener un comando para sacar los datos del archivo:
cat .data
Eso imprime los datos. Ahora, queremos crear un comando bash para establecer esos datos en una variable de entorno:
export DATA=`cat .data`
Ese comando toma los contenidos de .data y los pone en la variable de entorno DATA. Ahora, si pones eso dentro de un comando de alias, tienes un comando bash que establece tu variable de entorno:
alias set-data="export DATA=`cat .data`"
Puede poner ese comando de alias dentro de los archivos .bashrc o .bash_profile en su directorio de inicio para tener ese comando disponible en cualquier shell de bash nuevo que inicie.
Si establece variables de entorno dentro de un script de python (o cualquier otro script o programa), no afectará el shell primario.
Edite la aclaración: Entonces, la respuesta a su pregunta es sí, es verdad. Sin embargo, puede exportar desde un script de shell y obtenerlo mediante el uso de la invocación de puntos
en fooexport.sh
export FOO="bar"
en el símbolo del sistema
$ . ./fooexport.sh
$ echo $FOO
bar
Una solución consiste en enviar comandos de export
y que el shell principal evalúe esto.
thescript.py
:
import pipes
import random
r = random.randint(1,100)
print("export BLAHBLAH=%s" % (pipes.quote(str(r))))
..y el alias bash (lo mismo se puede hacer en la mayoría de las conchas ... ¡incluso tcsh!):
alias setblahblahenv="eval $(python thescript.py)"
Uso:
$ echo $BLAHBLAH
$ setblahblahenv
$ echo $BLAHBLAH
72
Puede generar cualquier código de shell arbitrario, incluidos varios comandos como:
export BLAHBLAH=23 SECONDENVVAR=''something else'' && echo ''everything worked''
Solo recuerde tener cuidado con el escape de cualquier salida creada dinámicamente (el módulo pipes.quote
es bueno para esto)