web-dev-qa-db-fra.com

Comment référencer un fichier pour des variables utilisant Bash?

Je veux appeler un fichier de paramètres pour une variable, comment puis-je faire cela en bash?

Ainsi, le fichier de paramètres définira les variables (par exemple, CONFIG.FILE):

production="liveschool_joe"
playschool="playschool_joe"

Et le script utilisera ces variables

#!/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

Comment puis-je obtenir bash de faire quelque chose comme ça? Devrai-je utiliser awk/sed, etc.?

128
edumike

La réponse courte

Utilisez la commande source.


Un exemple utilisant source

Par exemple:

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

Notez que la sortie de sh ./script.sh dans cet exemple est:

~$ sh ./script.sh 
playschool_joe
liveschool_joe

En effet, la commande source exécute le programme. Tout dans config.sh est exécuté.


Autrement

Vous pouvez utiliser la commande intégrée export et obtenir et définir des "variables d'environnement" peut également y parvenir.

Exécuter export et echo $ENV devrait être tout ce que vous devez savoir sur l’accès aux variables. L'accès aux variables d'environnement se fait de la même manière qu'une variable locale.

Pour les définir, dites:

export variable=value

à la ligne de commande. Tous les scripts pourront accéder à cette valeur.

209
Ezra

encore plus court en utilisant le point:

#!/bin/bash
. CONFIG_FILE

Sudo -u wwwrun svn up /srv/www/htdocs/$production
Sudo -u wwwrun svn up /srv/www/htdocs/$playschool
22
artistoex

Utilisez la commande source pour importer d'autres 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
13
Daniel

J'ai le même problème spécialement en cas de sécurité et j'ai trouvé la solution ici .

Mon problème était que, je voulais écrire un script de déploiement en bash avec un fichier de configuration contenant un chemin d'accès comme celui-ci.

################### 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"

Une solution existante consiste à utiliser la commande "SOURCE" et à importer le fichier de configuration avec ces variables. 'Chemin SOURCE/vers/fichier' Mais cette solution pose un problème de sécurité car le fichier source peut contenir tout ce qu'un script Bash peut contenir. Cela crée des problèmes de sécurité. Une personne malicicios peut "exécuter" du code arbitraire lorsque votre script recherche son fichier de configuration.

Imaginez quelque chose comme ça:

 ################### 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 ~/*

Pour résoudre ce problème, nous voudrons peut-être n'autoriser que les constructions de la forme NAME=VALUE de ce fichier (syntaxe d'attribution de variable) et éventuellement des commentaires (bien que techniquement, les commentaires ne soient pas importants). Donc, nous pouvons vérifier le fichier de configuration en utilisant egrep équivalent à la commande de grep -E.

Voici comment j'ai résolu le problème.

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
11
Erman

dans Bash, pour obtenir le résultat d'une commande, au lieu d'un fichier:

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

référence

7
zhazha

Conversion du fichier de paramètres en variables d'environnement

Habituellement, je vais analyser au lieu de rechercher des sources afin d'éviter la complexité de certains artefacts de mon fichier. Il me propose également des moyens de gérer spécialement les citations et autres choses. Mon objectif principal est de conserver ce qui vient après le '=' comme un littéral, même les guillemets doubles et les espaces.

#!/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"

Notez le petit truc que je devais faire pour considérer mon texte cité comme un paramètre unique avec un espace pour ma fonction cntpars. Un niveau d'évaluation supplémentaire était requis. Si je ne le faisais pas, comme dans l'option 2, j'aurais passé 2 paramètres comme suit:

  • "value
  • content"

Les guillemets doubles pendant l'exécution de la commande permettent de conserver les guillemets du fichier de paramètres. Par conséquent, la 3ème option échoue également.

L’autre option consisterait bien entendu à ne pas simplement fournir de variables entre guillemets, comme dans l’option 4, puis à vous assurer de les citer en cas de besoin.

Juste quelque chose à garder à l'esprit.

Recherche en temps réel

Une autre chose que j'aime faire est de faire une recherche en temps réel, en évitant l'utilisation de variables d'environnement:

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}"

Pas le plus efficace, mais avec des fichiers plus petits fonctionne très proprement.

3
YoYo

Si les variables sont générées et ne sont pas enregistrées dans un fichier, vous ne pouvez pas les transférer dans source. La façon la plus simple de le faire est la suivante:

some command | xargs
2
Elliot Chance