Как ссылаться на файл для переменных, используя Bash? - PullRequest
128 голосов
/ 08 марта 2011

Я хочу вызвать файл настроек для переменной, как я могу сделать это в bash?

Таким образом, файл настроек определит переменные (например: CONFIG.FILE):

production="liveschool_joe"
playschool="playschool_joe"

И скрипт будет использовать эти переменные в нем

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

Как заставить bash сделать что-то подобное?Придется ли мне использовать awk / sed и т.д ...?

Ответы [ 9 ]

205 голосов
/ 08 марта 2011

Краткий ответ

Используйте команду source.


Пример использования source

Например:

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

Обратите внимание, что в этом примере вывод sh ./script.sh:

~$ sh ./script.sh 
playschool_joe
liveschool_joe

Это потому, что *Команда 1022 * фактически запускает программу.Все в config.sh выполняется.


Другой способ

Вы можете использовать встроенную команду export, и получение и установка «переменных окружения» также могут выполнить это.

Запуск export и echo $ENV должен быть всем, что вам нужно знать о доступе к переменным.Доступ к переменным среды осуществляется так же, как и к локальной переменной.

Чтобы установить их, произнесите:

export variable=value

в командной строке.Все сценарии смогут получить доступ к этому значению.

22 голосов
/ 08 марта 2011

еще короче, используя точку:

#!/bin/bash
. CONFIG_FILE

sudo -u wwwrun svn up /srv/www/htdocs/$production
sudo -u wwwrun svn up /srv/www/htdocs/$playschool
13 голосов
/ 08 марта 2011

Используйте команду source для импорта других сценариев:

#!/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
11 голосов
/ 22 марта 2016

У меня такая же проблема, особенно в плане безопасности, и я нашел решение здесь .

Моя проблема заключалась в том, что я хотел написать сценарий развертывания в bash с файлом конфигурацииэто содержимое некоторого пути, подобного этому.

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

Существующее решение состоит из использования команды «SOURCE» и импорта файла конфигурации с этими переменными.'SOURCE путь / к / файлу' Но у этого решения есть некоторая проблема безопасности, потому что исходный файл может содержать все, что может сценарий Bash.Это создает проблемы безопасности.Специалист по malicicios может «выполнить» произвольный код, когда ваш скрипт использует свой конфигурационный файл.

Представьте что-то вроде этого:

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

Чтобы решить эту проблему, мы можем разрешить только конструкцииформа NAME=VALUE в этом файле (синтаксис назначения переменных) и, возможно, комментарии (хотя технически комментарии не важны).Итак, мы можем проверить файл конфигурации, используя egrep команду, эквивалентную grep -E.

Вот как я решил проблему.

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
7 голосов
/ 19 декабря 2015

в Bash, чтобы получить вывод какой-либо команды вместо файла:

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

ссылка

3 голосов
/ 17 ноября 2016

Преобразование файла параметров в переменные окружения

Обычно я занимаюсь разбором вместо поиска, чтобы избежать сложностей определенных артефактов в моем файле.Он также предлагает мне способы специально обрабатывать кавычки и другие вещи.Моя главная цель - сохранить все, что следует после '=', в виде литерала, даже двойные кавычки и пробелы.

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

Обратите внимание на небольшую хитрость, которую я должен был сделать, чтобы рассматривать мой цитируемый текст как один параметрс пробелом к ​​моей cntpars функции.Был один дополнительный уровень оценки требуется.Если бы я не сделал этого, как в варианте 2, я бы передал 2 параметра следующим образом:

  • "value
  • content"

Двойные кавычки во время выполнения команды приводят к сохранению двойных кавычек из файла параметров.Следовательно, 3-й вариант также завершается неудачей.

Другой вариант, конечно, состоит в том, чтобы просто не указывать переменные в двойных кавычках, как в варианте 4, а затем просто проверять их в кавычках при необходимости.

Просто то, что нужно иметь в виду.

Поиск в режиме реального времени

Еще одна вещь, которую мне нравится делать, - это выполнять поиск в реальном времени, избегая использования переменных среды:

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

Не самый эффективный, но с небольшими файлами работает очень чисто.

2 голосов
/ 29 июля 2015

Если переменные генерируются и не сохраняются в файл, их нельзя передать в source.Обманчиво простой способ сделать это так:

some command | xargs
0 голосов
/ 18 января 2019

Для предотвращения конфликтов имен, импортируйте только те переменные, которые вам нужны:

variableInFile () {
    variable="${1}"
    file="${2}"

    echo $(
        source "${file}";
        eval echo \$\{${variable}\}
    )
}
0 голосов
/ 27 июля 2017

Сценарий, содержащий переменные, может быть выполнен импортированным с использованием bash.Рассмотрим скрипт-variable.sh

#!/bin/sh
scr-var=value

Рассмотрим фактический скрипт, где будет использоваться переменная:

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