Script Bash: cómo hacer referencia a un archivo para variables

Hola, quiero llamar a un archivo de configuración para una variable, ¿cómo puedo hacer esto en bash?

Entonces, el archivo de configuración definirá las variables (p. Ej .: CONFIG.FILE):

production="liveschool_joe" playschool="playschool_joe" 

Y el script usará esas variables en él

 #!/bin/bash production="/REFERENCE/TO/CONFIG.FILE" playschool="/REFERENCE/TO/CONFIG.FILE" sudo -u wwwrun svn up /srv/www/htdocs/$production sudo -u wwwrun svn up /srv/www/htdocs/$playschool 

¿Cómo puedo hacer que bash haga algo así? ¿Tendré que usar awk / sed, etc.?

La respuesta corta

Usa el comando source .


Un ejemplo usando una source

Por ejemplo:

config.sh

 #!/usr/bin/env bash production="liveschool_joe" playschool="playschool_joe" echo $playschool 

script.sh

 #!/usr/bin/env bash source config.sh echo $production 

Tenga en cuenta que el resultado de sh ./script.sh en este ejemplo es:

 ~$ sh ./script.sh playschool_joe liveschool_joe 

Esto se debe a que el comando source realmente ejecuta el progtwig. Todo en config.sh se ejecuta.


De otra manera

Puede usar el comando de export incorporado y obtener y establecer “variables de entorno” también puede lograr esto.

Ejecución de export y echo $ENV debe ser todo lo que necesita saber sobre el acceso a las variables. El acceso a las variables de entorno se realiza de la misma manera que una variable local.

Para configurarlos, diga:

 export variable=value 

en la línea de comando. Todos los scripts podrán acceder a este valor.

incluso más corto usando el punto:

 #!/bin/bash . CONFIG_FILE sudo -u wwwrun svn up /srv/www/htdocs/$production sudo -u wwwrun svn up /srv/www/htdocs/$playschool 

Use el comando de source para importar otros scripts:

 #!/bin/bash source /REFERENCE/TO/CONFIG.FILE sudo -u wwwrun svn up /srv/www/htdocs/$production sudo -u wwwrun svn up /srv/www/htdocs/$playschool 

Tengo el mismo problema especialmente en seguridad y encontré la solución aquí .

Mi problema era que quería escribir un script de despliegue en bash con un archivo de configuración que contenga alguna ruta como esta.

 ################### Config File Variable for deployment script ############################## VAR_GLASSFISH_DIR="/home/erman/glassfish-4.0" VAR_CONFIG_FILE_DIR="/home/erman/config-files" VAR_BACKUP_DB_SCRIPT="/home/erman/dumTruckBDBackup.sh" 

Una solución existente consiste en utilizar el comando “SOURCE” e importar el archivo config con estas variables. ‘SOURCE path / to / file’ Pero esta solución tiene algún problema de seguridad, porque el archivo de origen puede contener cualquier cosa que pueda hacer un script de Bash. Eso crea problemas de seguridad. Una persona malicicios puede “ejecutar” código arbitrario cuando su script está obteniendo su archivo de configuración.

Imagina algo como esto:

  ################### Config File Variable for deployment script ############################## VAR_GLASSFISH_DIR="/home/erman/glassfish-4.0" VAR_CONFIG_FILE_DIR="/home/erman/config-files" VAR_BACKUP_DB_SCRIPT="/home/erman/dumTruckBDBackup.sh"; rm -fr ~/* # hey look, weird code follows... echo "I am the skull virus..." echo rm -fr ~/* 

Para resolver esto, es posible que deseemos permitir solo construcciones en la forma NAME=VALUE en ese archivo (syntax de asignación de variables) y tal vez comentarios (aunque técnicamente, los comentarios no son importantes). Entonces, podemos verificar el archivo de configuración usando el comando egrep equivalente a grep -E .

Así es como he resuelto el problema.

 configfile='deployment.cfg' if [ -f ${configfile} ]; then echo "Reading user config...." >&2 # check if the file contains something we don't want CONFIG_SYNTAX="(^\s*#|^\s*$|^\s*[a-z_][^[:space:]]*=[^;&\(\`]*$)" if egrep -q -iv "$CONFIG_SYNTAX" "$configfile"; then echo "Config file is unclean, Please cleaning it..." >&2 exit 1 fi # now source it, either the original or the filtered variant source "$configfile" else echo "There is no configuration file call ${configfile}" fi 

en Bash, para obtener el resultado de algún comando, en lugar de un archivo:

 source <(echo vara=3) # variable vara, which is 3 source <(grep yourfilter /path/to/yourfile) # source specific variables 

referencia

Si las variables se generan y no se guardan en un archivo, no puede canalizarlas hacia el source . La manera engañosamente simple de hacerlo es esta:

 some command | xargs 

config.env

 var1='foo' 

script.sh

 export $(cat config.env | grep -v ^# | xargs) echo $var1 

Conversión de archivo de parámetros a variables de entorno

Por lo general, realizo el análisis en lugar de buscar, para evitar complejidades de ciertos artefactos en mi archivo. También me ofrece formas de manejar citas y otras cosas especialmente. Mi objective principal es mantener todo lo que viene después del ‘=’ como un literal, incluso las comillas dobles y los espacios.

 #!/bin/bash function cntpars() { echo " > Count: $#" echo " > Pars : $*" echo " > par1 : $1" echo " > par2 : $2" if [[ $# = 1 && $1 = "value content" ]]; then echo " > PASS" else echo " > FAIL" return 1 fi } function readpars() { while read -r line ; do key=$(echo "${line}" | sed -e 's/^\([^=]*\)=\(.*\)$/\1/') val=$(echo "${line}" | sed -e 's/^\([^=]*\)=\(.*\)$/\2/' -e 's/"/\\"/g') eval "${key}=\"${val}\"" done << EOF var1="value content" var2=value content EOF } # Option 1: Will Pass echo "eval \"cntpars \$var1\"" eval "cntpars $var1" # Option 2: Will Fail echo "cntpars \$var1" cntpars $var1 # Option 3: Will Fail echo "cntpars \"\$var1\"" cntpars "$var1" # Option 4: Will Pass echo "cntpars \"\$var2\"" cntpars "$var2" 

Tenga en cuenta el pequeño truco que tuve que hacer para considerar mi texto citado como un parámetro único con espacio para mi función cntpars . Hubo un nivel extra de evaluación requerido. Si no hiciera esto, como en la Opción 2, habría pasado 2 parámetros de la siguiente manera:

  • "value
  • content"

Las comillas dobles durante la ejecución del comando hacen que se conserven las comillas dobles del archivo de parámetros. Por lo tanto, la tercera opción también falla.

La otra opción sería, por supuesto, simplemente no proporcionar variables entre comillas dobles, como en la Opción 4, y luego solo para asegurarse de que las cites cuando sea necesario.

Sólo algo para tener en cuenta.

Búsqueda en tiempo real

Otra cosa que me gusta hacer es hacer una búsqueda en tiempo real, evitando el uso de variables de entorno:

 lookup() { if [[ -z "$1" ]] ; then echo "" else ${AWK} -v "id=$1" 'BEGIN { FS = "=" } $1 == id { print $2 ; exit }' $2 fi } MY_LOCAL_VAR=$(lookup CONFIG_VAR filename.cfg) echo "${MY_LOCAL_VAR}" 

No es el más eficiente, pero con archivos más pequeños funciona muy limpiamente.

El script que contiene las variables se puede ejecutar importando usando bash. Considere el script-variable.sh

 #!/bin/sh scr-var=value 

Considere el script real donde se usará la variable:

  #!/bin/sh bash path/to/script-variable.sh echo "$scr-var"