TL; DR: ¿Cómo exporto un conjunto de pares clave / valor de un archivo de texto al entorno de shell?
Para el registro, a continuación se muestra la versión original de la pregunta, con ejemplos.
Estoy escribiendo un script en bash que analiza archivos con 3 variables en una carpeta determinada, esta es una de ellas:
MINIENTREGA_FECHALIMITE="2011-03-31"
MINIENTREGA_FICHEROS="informe.txt programa.c"
MINIENTREGA_DESTINO="./destino/entrega-prac1"
Este archivo se almacena en ./conf/prac1
Mi script minientrega.sh luego analiza el archivo usando este código:
cat ./conf/$1 | while read line; do
export $line
done
Pero cuando ejecuto minientrega.sh prac1
en la línea de comando no establece las variables de entorno
También intenté usar source ./conf/$1
pero el mismo problema aún se aplica
Quizás haya otra forma de hacerlo, solo necesito usar las variables de entorno del archivo que paso como argumento de mi script.
bash
variables
environment-variables
hugo19941994
fuente
fuente
Respuestas:
Problema con el enfoque es el
export
delwhile
bucle está sucediendo en una cáscara de sub, y aquellos variable no estará disponible en el shell actual (shell padre del bucle while).Agregar
export
comando en el archivo en sí:Luego debe buscar el archivo en el shell actual usando:
O
fuente
export
no es ideal, el problema también puede ser fijado por el simple uso de redirección de entrada en el bucle:while read line; do ... ; done < ./conf/$1
.< <(commands that generate output)
set -o allexport
export
lo rompería para cosas como Java, SystemD u otras herramientasawk '{print "export " $0}' envfile
comando de conveniencia para anteponer la exportación al comienzo de cada líneaEsto puede ser útil:
La razón por la que uso esto es si quiero probar
.env
cosas en mi consola de rieles.A gabrielf se le ocurrió una buena manera de mantener las variables locales. Esto resuelve el problema potencial al pasar de un proyecto a otro.
He probado esto con
bash 3.2.51(1)-release
Actualizar:
Para ignorar las líneas que comienzan con
#
, use esto (gracias al comentario de Pete ):Y si desea
unset
todas las variables definidas en el archivo, use esto:Actualizar:
Para manejar también valores con espacios, use:
en sistemas GNU - o:
en sistemas BSD.
fuente
export $(cat .env)
pero no sé cómo lidiar con los espacios.-d
para configurar el delimitador, así que lo estoy intentandoenv $(cat .env | xargs -d '\n') rails
, pero todavía errores con un archivo que no se encuentra si.env
tiene espacios. ¿Alguna idea de por qué esto no funciona?eval $(cat .env) rails
-o allexport
permite exportar todas las siguientes definiciones de variables.+o allexport
deshabilita esta característica.fuente
.env
archivo tiene comentarios. ¡Gracias!set -o allexport; source conf-file; set +o allexport
set -a; . conf-file; set +a
.Si
env.txt
es como:Explicaciones -a es equivalente a allexport . En otras palabras, cada asignación de variable en el shell se exporta al entorno (para ser utilizada por múltiples procesos secundarios). Se puede encontrar más información en la documentación integrada de Set :
fuente
-a
es equivalente aallexport
. En otras palabras, cada asignación de variables en el shell seexport
edita en el entorno (para ser utilizado por múltiples procesos secundarios). También vea este artículo gnu.org/software/bash/manual/html_node/The-Set-Builtin.htmlLa
allexport
opción se menciona en un par de otras respuestas aquí, para lo cualset -a
es el acceso directo. Obtener el .env realmente es mejor que recorrer las líneas y exportar porque permite comentarios, líneas en blanco e incluso variables de entorno generadas por comandos. Mi .bashrc incluye lo siguiente:fuente
VAR=
.fuente
eval $(cat .env | sed 's/^[^$]/export /')
permite tener líneas vacías para una mejor legibilidad.cat .env | sed 's/^[^$]/export /'
elimina el carácter inicial. Es decir, para un archivoA=foo\nB=bar\n
que obtengoexport =foo\nexport =bar\n
. Esto funciona mejor para saltar líneas en blanco:cat .env | sed '/^$/! s/^/export /'
.cat
en ninguno de los casos:eval $(sed 's/^/export /' .env)
funciona igual de bien.)Encontré que la forma más eficiente es:
Explicación
Cuando tenemos un
.env
archivo como este:correr
xargs < .env
obtendrákey=val foo=bar
¡así que obtendremos un
export key=val foo=bar
y es exactamente lo que necesitamos!Limitación
fuente
env
producir este formato.Aquí hay otra
sed
solución, que no ejecuta eval o requiere ruby:Esto agrega exportación, manteniendo comentarios en líneas que comienzan con un comentario.
Contenidos .env
muestra de ejecución
Encontré esto especialmente útil al construir un archivo de este tipo para cargar en un archivo de unidad systemd, con
EnvironmentFile
.fuente
He votado a favor de la respuesta del usuario 4040650 porque es simple y permite comentarios en el archivo (es decir, líneas que comienzan con #), lo cual es muy deseable para mí, ya que se pueden agregar comentarios que explican las variables. Solo reescribiendo en el contexto de la pregunta original.
Si el script se llama como se indica:,
minientrega.sh prac1
entonces minientrega.sh podría tener:Lo siguiente se extrajo de la documentación establecida :
Y esto también:
fuente
Mejorando la respuesta de Silas Paul
exportar las variables en una subshell las convierte en locales para el comando.
(export $(cat .env | xargs) && rails c)
fuente
(set -a; source dev.env; set +a; rails c)
para tener también los beneficios del abastecimiento (por ejemplo, el script puede ejecutarse).SAVE=$(set +o | grep allexport) && set -o allexport && . .env; eval "$SAVE"
Esto guardará / restaurará sus opciones originales, cualesquiera que sean.
El uso
set -o allexport
tiene la ventaja de omitir correctamente los comentarios sin una expresión regular.set +o
por sí solo genera todas sus opciones actuales en un formato que bash puede ejecutar más tarde. También útil:set -o
por sí solo, muestra todas sus opciones actuales en formato amigable para los humanos.fuente
exec env -i bash
borraría el entorno existente antes de llamareval
si necesita desarmar variables que solo se establecen dentro.env
.El camino más corto que encontré:
Su
.env
archivo:Entonces solo
Bonificación: debido a que es una línea corta, es muy útil en el
package.json
archivofuente
VARIABLE_NAME="A_VALUE"
Más simple:
export
a todas las líneaseval
toda la cosaeval $(cat .env | sed -e /^$/d -e /^#/d -e 's/^/export /')
Otra opción (no tienes que correr
eval
(gracias a @Jaydeep)):Por último, si quieres hacer tu vida REALMENTE fácil, agrega esto a tu
~/.bash_profile
:function source_envfile() { export $(cat $1 | sed -e /^$/d -e /^#/d | xargs); }
(¡ASEGÚRESE DE QUE VUELVA A CARGAR SU CONFIGURACIÓN DE BASH!
source ~/.bash_profile
O ... simplemente haga una nueva pestaña / ventana y resuelva el problema) lo llama así:source_envfile .env
fuente
source <( echo $(sed -E -n 's/[^#]+/ &/ p' <(echo "${2}" | tr -d '\r')) );
. De alguna manera, gitlab guarda la variable secreta con un retorno de carro de Windows, así que tuve que recortar eso contr -d '\r'
.Puede usar su script original para configurar las variables, pero debe llamarlo de la siguiente manera (con un punto independiente):
También puede haber un problema con el
cat | while read
enfoque. Yo recomendaría usar el enfoquewhile read line; do .... done < $FILE
.Aquí hay un ejemplo de trabajo:
fuente
test.conf
como un archivo de script. Eso lo hace mejor. Es más seguro no permitir secuencias de comandos a menos que realmente lo necesite, especialmente si alguien no se da cuenta de que eso está sucediendo (u olvida).A partir de otras respuestas, aquí hay una manera de exportar solo un subconjunto de líneas en un archivo, incluidos valores con espacios como
PREFIX_ONE="a word"
:fuente
Aquí está mi variante:
en comparación con las soluciones anteriores:
.env
no están expuestos a la persona que llama)set
opcionesset -a
.
lugar desource
evitar el bashism.env
falla la cargafuente
set -a && . ./.env && "$@" && echo "your comand here"
Trabajo con docker-compose y
.env
archivos en Mac, y quería importarlos.env
a mi shell bash (para probar), y la "mejor" respuesta aquí fue tropezar con la siguiente variable:.env
Solución
Así que terminé usando
eval
y envolviendo mis definiciones de env env en comillas simples.Versión Bash
fuente
Mi .env:
Invocando:
Referencia /unix/79068/how-to-export-variables-that-are-set-all-at-once
fuente
Tengo problemas con las soluciones sugeridas anteriormente:
$()
hace un desastre.Aquí está mi solución, que sigue siendo bastante terrible para la OMI, y no resuelve el problema de "exportar solo a un niño" abordado por Silas (aunque probablemente pueda ejecutarlo en un sub-shell para limitar el alcance):
fuente
Mis requisitos fueron:
export
prefijos (para compatibilidad con dotenv)Versión de trabajo completa compilada de las respuestas anteriores:
fuente
Primero, cree un archivo de entorno que tenga todos los pares clave-valor de los entornos como a continuación y asígnele el nombre que desee en mi caso, es
env_var.env
Luego cree un script que exportará todas las variables de entorno para el entorno de Python como se muestra a continuación y asígnele el nombre
export_env.sh
Este script tomará el primer argumento como el archivo de entorno y luego exportará todas las variables de entorno en ese archivo y luego ejecutará el comando después de eso.
USO:
fuente
Encontré este hilo cuando intentaba reutilizar Docker
--env-file
s en un shell. Su formato no es compatible con bash, pero es simple:name=value
sin comillas ni sustituciones. También ignoran las líneas en blanco y los#
comentarios.No pude conseguir que sea compatible con posix, pero aquí hay uno que debería funcionar en shells tipo bash (probado en zsh en OSX 10.12.5 y bash en Ubuntu 14.04):
Que no va a manejar tres casos en el ejemplo de los documentos relacionados anteriormente:
bash: export: `123qwe=bar': not a valid identifier
bash: export: `org.spring.config=something': not a valid identifier
FOO
)fuente
Espacios en blanco en el valor
Aquí hay muchas respuestas excelentes, pero encontré que a todas les falta soporte para el espacio en blanco en el valor:
He encontrado 2 soluciones que funcionan con dichos valores con soporte para líneas vacías y comentarios.
Uno basado en sed y @ javier-buzzi responden :
Y uno con línea de lectura en un bucle basado en la respuesta @ john1024
La clave aquí es usar
declare -x
y poner la línea entre comillas dobles. No sé por qué, pero cuando vuelves a formatear el código de bucle en varias líneas, no funcionará: no soy un programador de bash, simplemente engullí estos, todavía es mágico para mí :)fuente
sed
solución para que funcione. Pero primero alguna explicación:-e
es la abreviatura de--expression
, que simplemente dicesed
qué operaciones tomar.-e /^$/d
elimina las líneas vacías de la salida (no el archivo).-e /^#/d
elimina los comentarios bash (líneas que comienzan con #) de la salida.'s/.*/declare -x "&"/g'
reemplaza (sustituye) las líneas restantes condeclare -x "ENV_VAR="VALUE""
. Cuando obtienes esto, al menos para mí, no funcionó. En cambio, tuve que usarsource <(sed -e /^$/d -e /^#/d -e 's/.*/declare -x &/g' .env)
, para quitar el"
envoltorio extra .ENV_VAR="lorem ipsum"
, tengoENV_VAR=lorem ipsum
, sin comillas en el archivo .env. Ahora no estoy seguro de por qué, pero esto probablemente fue problemático en otras herramientas que analizan este archivo. Y en lugar delorem ipsum
terminar con"lorem ipsum"
valor, con comillas. Gracias por las explicaciones :)ENV_VAR="lorem ipsum"
. En mi caso de uso, mi proveedor de alojamiento genera este archivo en función de algunas opciones de configuración que he establecido e insertan las comillas dobles. Por lo tanto, me veo obligado a solucionarlo. Gracias por su ayuda aquí, ¡me ahorró mucho tiempo tratando de encontrar lassed
opciones correctas !prueba algo como esto
fuente
Cómo funciona
.env
archivo Todas las variables se exportarán al entorno actual.declare -x VAR="val"
que exportaría cada una de las variables al entorno.Caracteristicas
.env
puede tener comentarios.env
puede tener líneas vacías.env
no requiere encabezado o pie de página especial como en las otras respuestas (set -a
yset +a
).env
no requiere tenerexport
para cada valorfuente
Si obtiene un error porque una de sus variables contiene un valor que contiene espacios en blanco, puede intentar restablecer bash
IFS
(Separador de campo interno)\n
para permitir que bash interprete elcat .env
resultado como una lista de parámetros para elenv
ejecutable.Ejemplo:
Ver también:
fuente
Mi archivo .env se ve así:
Usando las formas de @henke , el valor exportado termina conteniendo comillas
"
Pero quiero que el valor exportado contenga solo:
Para solucionarlo, edito el comando para eliminar las comillas:
fuente
Éste hace frente a espacios en el RHS y omite variables "extrañas" como las definiciones de módulos bash (con '()' en ellas):
fuente