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 prac1en la línea de comando no establece las variables de entorno
También intenté usar source ./conf/$1pero 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
exportdelwhilebucle está sucediendo en una cáscara de sub, y aquellos variable no estará disponible en el shell actual (shell padre del bucle while).Agregar
exportcomando en el archivo en sí:Luego debe buscar el archivo en el shell actual usando:
O
fuente
exportno 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 allexportexportlo rompería para cosas como Java, SystemD u otras herramientasawk '{print "export " $0}' envfilecomando 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
.envcosas 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)-releaseActualizar:
Para ignorar las líneas que comienzan con
#, use esto (gracias al comentario de Pete ):Y si desea
unsettodas 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.-dpara 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.envtiene espacios. ¿Alguna idea de por qué esto no funciona?eval $(cat .env) rails-o allexportpermite exportar todas las siguientes definiciones de variables.+o allexportdeshabilita esta característica.fuente
.envarchivo tiene comentarios. ¡Gracias!set -o allexport; source conf-file; set +o allexportset -a; . conf-file; set +a.Si
env.txtes 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
-aes equivalente aallexport. En otras palabras, cada asignación de variables en el shell seexportedita 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
allexportopción se menciona en un par de otras respuestas aquí, para lo cualset -aes 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\nque obtengoexport =foo\nexport =bar\n. Esto funciona mejor para saltar líneas en blanco:cat .env | sed '/^$/! s/^/export /'.caten 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
.envarchivo como este:correr
xargs < .envobtendrákey=val foo=bar¡así que obtendremos un
export key=val foo=bary es exactamente lo que necesitamos!Limitación
fuente
envproducir este formato.Aquí hay otra
sedsolució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 prac1entonces 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 allexporttiene la ventaja de omitir correctamente los comentarios sin una expresión regular.set +opor sí solo genera todas sus opciones actuales en un formato que bash puede ejecutar más tarde. También útil:set -opor sí solo, muestra todas sus opciones actuales en formato amigable para los humanos.fuente
exec env -i bashborraría el entorno existente antes de llamarevalsi necesita desarmar variables que solo se establecen dentro.env.El camino más corto que encontré:
Su
.envarchivo:Entonces solo
Bonificación: debido a que es una línea corta, es muy útil en el
package.jsonarchivofuente
VARIABLE_NAME="A_VALUE"Más simple:
exporta todas las líneasevaltoda 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_profileO ... simplemente haga una nueva pestaña / ventana y resuelva el problema) lo llama así:source_envfile .envfuente
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 readenfoque. Yo recomendaría usar el enfoquewhile read line; do .... done < $FILE.Aquí hay un ejemplo de trabajo:
fuente
test.confcomo 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:
.envno están expuestos a la persona que llama)setopcionesset -a.lugar desourceevitar el bashism.envfalla la cargafuente
set -a && . ./.env && "$@" && echo "your comand here"Trabajo con docker-compose y
.envarchivos en Mac, y quería importarlos.enva mi shell bash (para probar), y la "mejor" respuesta aquí fue tropezar con la siguiente variable:.env
Solución
Así que terminé usando
evaly 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:
exportprefijos (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.envLuego 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.shEste 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-files en un shell. Su formato no es compatible con bash, pero es simple:name=valuesin 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 identifierbash: export: `org.spring.config=something': not a valid identifierFOO)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 -xy 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
sedsolución para que funcione. Pero primero alguna explicación:-ees la abreviatura de--expression, que simplemente dicesedqué operaciones tomar.-e /^$/delimina las líneas vacías de la salida (no el archivo).-e /^#/delimina 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 ipsumterminar 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 lassedopciones correctas !prueba algo como esto
fuente
Cómo funciona
.envarchivo Todas las variables se exportarán al entorno actual.declare -x VAR="val"que exportaría cada una de las variables al entorno.Caracteristicas
.envpuede tener comentarios.envpuede tener líneas vacías.envno requiere encabezado o pie de página especial como en las otras respuestas (set -ayset +a).envno requiere tenerexportpara 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)\npara permitir que bash interprete elcat .envresultado como una lista de parámetros para elenvejecutable.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