variable una sirven script resultado que pasar parametros para las guardar funciones entorno cómo configuran con como comando bash variables environment-variables

bash - una - Establecer variables de entorno desde el archivo de valores clave/par



variables en bash (19)

Espacios blancos en el valor.

Hay muchas respuestas excelentes aquí, pero encontré que todas carecen de soporte para espacios en blanco en el valor:

DATABASE_CLIENT_HOST=host db-name db-user 0.0.0.0/0 md5

He encontrado 2 soluciones que funcionan con dichos valores con soporte para líneas vacías y comentarios.

Una basada en sed y @ javier-buzzi answer :

source <(sed -e /^$/d -e /^#/d -e ''s/.*/declare -x "&"/g'' .env)

Y uno con línea de lectura en un bucle basado en la answer @ john1024

while read -r line; do declare -x "$line"; done < <(egrep -v "(^#|^/s|^$)" .env)

La clave aquí es usar declare -x y poner la línea entre comillas dobles. No sé por qué, pero cuando reformateas el código de bucle a varias líneas, no funcionará. No soy un programador de bash, simplemente las engullí, todavía me parece mágico :)

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 es 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 comandos no establece las variables de entorno

También intenté usar source ./conf/$1 pero el mismo problema sigue siendo válido.

Tal vez haya alguna otra forma de hacer esto, solo necesito usar las variables de entorno del archivo que paso como argumento de mi script.


A partir de otras respuestas, aquí hay una manera de exportar solo un subconjunto de líneas en un archivo, incluidos los valores con espacios como PREFIX_ONE="a word" :

set -a . <(grep ''^[ ]*PREFIX_'' conf-file) set +a


Aquí hay otra solución sed , que no ejecuta eval ni requiere ruby:

source <(sed -E -n ''s/[^#]+/export &/ p'' ~/.env)

Esto agrega exportación, manteniendo comentarios en las líneas que comienzan con un comentario.

contenidos .env

A=1 #B=2

ejecución de la muestra

$ sed -E -n ''s/[^#]+/export &/ p'' ~/.env export A=1 #export B=2

Encontré esto especialmente útil al construir un archivo para cargarlo en un archivo de unidad del sistema, con EnvironmentFile .


El problema con su enfoque es la export en el bucle while que está ocurriendo en un sub shell, y esas variables no estarán disponibles en el shell actual (shell primario del bucle while).

Agregue export comando de export en el propio archivo:

export MINIENTREGA_FECHALIMITE="2011-03-31" export MINIENTREGA_FICHEROS="informe.txt programa.c" export MINIENTREGA_DESTINO="./destino/entrega-prac1"

Entonces necesitas fuente en el archivo en el shell actual usando:

. ./conf/prac1

O

source ./conf/prac1


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, sin sustitución. También ignoran líneas en blanco y # comentarios.

No podía tenerlo totalmente compatible con Posix, pero aquí hay uno que debería funcionar en shells similares a bash (probado en zsh en OSX 10.12.5 y bash en Ubuntu 14.04):

while read -r l; do export "$(sed ''s/=.*$//'' <<<$l)"="$(sed -E ''s/^[^=]+=//'' <<<$l)"; done < <(grep -E -v ''^/s*(#|$)'' your-env-file)

No manejará tres casos en el ejemplo de los documentos vinculados anteriormente:

  • bash: export: `123qwe=bar'': not a valid identifier
  • bash: export: `org.spring.config=something'': not a valid identifier
  • y no manejará la sintaxis de paso (un FOO desnudo)

Esto podría ser útil:

export $(cat .env | xargs) && rails c

La razón por la que uso esto es si quiero probar cosas .env en mi consola de rieles.

gabrielf ideó una buena manera de mantener las variables locales. Esto resuelve el problema potencial al pasar de un proyecto a otro.

env $(cat .env | xargs) rails

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 ):

export $(grep -v ''^#'' .env | xargs)

Y si desea unset todas las variables definidas en el archivo, use esto:

unset $(grep -v ''^#'' .env | sed -E ''s/(.*)=.*//1/'' | xargs)

Actualizar:

Para manejar también valores con espacios, usa:

export $(grep -v ''^#'' .env | xargs -d ''/n'')

en sistemas GNU o:

export $(grep -v ''^#'' .env | xargs -0)

en los sistemas BSD.


He actualizado la respuesta del usuario 4040650 porque es a la vez simple y permite comentarios en el archivo (es decir, líneas que comienzan con #), lo cual es muy conveniente para mí, ya que se pueden agregar comentarios que expliquen las variables. Solo reescribiendo en el contexto de la pregunta original.

Si el script está escrito como se indica: minientrega.sh prac1 , entonces minientrega.sh podría tener:

set -a # export all variables created next source $1 set +a # stop exporting # test that it works echo "Ficheros: $MINIENTREGA_FICHEROS"

Lo siguiente fue extraído de la gnu.org/software/bash/manual/html_node/The-Set-Builtin.html :

Esta estructura es tan complicada que merece su propia sección. set le permite cambiar los valores de las opciones de shell y establecer los parámetros posicionales, o mostrar los nombres y valores de las variables de shell.

set [--abefhkmnptuvxBCEHPT] [-o option-name] [argumento ...] set [+ abefhkmnptuvxBCEHPT] [+ o option-name] [argumento ...]

Si no se proporcionan opciones o argumentos, set muestra los nombres y valores de todas las funciones y variables de shell, ordenados según la configuración regional actual, en un formato que puede reutilizarse como entrada para configurar o restablecer las variables establecidas actualmente. Las variables de solo lectura no se pueden restablecer. En el modo POSIX, solo se muestran las variables de shell.

Cuando se suministran opciones, establecen o anulan atributos de shell. Las opciones, si se especifican, tienen los siguientes significados:

-a Cada variable o función que se crea o modifica recibe el atributo de exportación y se marca para exportar al entorno de los comandos subsiguientes.

Y esto también:

El uso de ''+'' en lugar de ''-'' hace que estas opciones se desactiven. Las opciones también se pueden usar al invocar el shell. El conjunto actual de opciones se puede encontrar en $ -.


La opción allexport se menciona en un par de otras respuestas aquí, para las cuales set -a es el acceso directo. Adquirir el .env realmente es mejor que recorrer las líneas y exportar, ya que permite comentarios, líneas en blanco e incluso variables de entorno generadas por comandos. Mi .bashrc incluye lo siguiente:

# .env loading in the shell dotenv () { set -a [ -f .env ] && . .env set +a } # Run dotenv on login dotenv # Run dotenv on every new directory cd () { builtin cd $@ dotenv }


Más simple:

  1. agarrar el contenido del archivo
  2. elimina cualquier línea en blanco (solo en caso de que hayas separado algunas cosas)
  3. eliminar cualquier comentario (solo en caso de que hayas añadido algunos ...)
  4. Añadir export a todas las líneas.
  5. eval todo

eval $(cat .env | sed -e /^$/d -e /^#/d -e ''s/^/export /'')

Otra opción (no tienes que ejecutar eval (gracias a @Jaydeep)):

export $(cat .env | sed -e /^$/d -e /^#/d | xargs)

Por último, si desea que su vida sea REALMENTE fácil, agregue esto a su ~/.bash_profile :

function source_envfile() { export $(cat $1 | sed -e /^$/d -e /^#/d | xargs); }

(¡ASEGÚRESE DE QUE source_envfile .env SUS CONFIGURACIONES DE BASH! source ~/.bash_profile o ... simplemente haga una nueva pestaña / ventana y el problema se solucione) lo llama así: source_envfile .env


Mejorando la respuesta de Silas Paul

exportar las variables en una subshell las hace locales al comando.

(export $(cat .env | xargs) && rails c)



Puede usar su script original para establecer las variables, pero necesita llamarlo de la siguiente manera (con un punto independiente):

. ./minientrega.sh

También podría haber un problema con el cat | while read cat | while read enfoque. Yo recomendaría usar el enfoque while read line; do .... done < $FILE while read line; do .... done < $FILE .

Aquí hay un ejemplo de trabajo:

> cat test.conf VARIABLE_TMP1=some_value > cat run_test.sh #/bin/bash while read line; do export "$line"; done < test.conf echo "done" > . ./run_test.sh done > echo $VARIABLE_TMP1 some_value


Si desea cargar su archivo .env en el proceso en ejecución dentro del código de Visual Studio, puede agregar una referencia a su archivo .env en su launch.json usando la propiedad envFile :

"configurations": [ { "name": "Launch server.js with .env", "type": "node", "request": "launch", "envFile": "${workspaceRoot}/.env", ... } ]



Tengo problemas con las soluciones sugeridas anteriormente:

  • La solución de @ anubhava hace que la escritura de archivos de configuración amigables de bash sea muy molesta muy rápido, y además, es posible que no desee exportar siempre su configuración.
  • La solución de @Silas Paul se rompe cuando tienes variables que tienen espacios u otros caracteres que funcionan bien en valores entre comillas, pero $() hace que se desordenen.

Aquí está mi solución, que sigue siendo una OMI bastante terrible, y no resuelve el problema de "exportar solo a un hijo" abordado por Silas (aunque probablemente pueda ejecutarlo en una sub-shell para limitar el alcance):

source .conf-file export $(cut -d= -f1 < .conf-file)


-o allexport permite -o allexport todas las siguientes definiciones de variables. +o allexport deshabilita esta característica.

set -o allexport source conf-file set +o allexport


SAVE=$(set +o) && set -o allexport && . .env; eval "$SAVE"

Esto guardará / restaurará sus opciones originales, cualesquiera que sean.

El uso de set -o allexport tiene la ventaja de omitir correctamente los comentarios sin una expresión regular.

set +o por sí mismo genera todas las opciones actuales en un formato que luego puede ejecutar bash. También es práctico: set -o por sí mismo, genera todas sus opciones actuales en un formato amigable para el usuario.


eval $(cat .env | sed ''s/^/export /'')


set -a . ./env.txt set +a

Si env.txt es como:

VAR1=1 VAR2=2 VAR3=3 ...