Как ссылаться на файл для переменных, используя Bash?

Я хочу вызвать файл настроек для переменной, как я могу сделать это в 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 и т.д.?

Ответ 1

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

Используйте команду 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

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


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

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

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

Чтобы установить их, скажите:

export variable=value

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

Ответ 2

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

#!/bin/bash
. CONFIG_FILE

sudo -u wwwrun svn up /srv/www/htdocs/$production
sudo -u wwwrun svn up /srv/www/htdocs/$playschool

Ответ 3

Используйте команду 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

Ответ 4

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

Моя проблема заключалась в том, что я хотел написать сценарий развертывания на 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

Ответ 5

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

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

ссылка

Ответ 6

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

some command | xargs

Ответ 7

Преобразование файла параметров в переменные среды

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

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

Двойное цитирование во время выполнения команды вызывает сохранение двойных кавычек из файла параметров. Следовательно, третий вариант также не работает.

Другим вариантом было бы, конечно, просто не предоставлять переменные в двойных кавычках, как в Варианте 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}"

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

Ответ 8

config.env

var1='foo'

script.sh

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

Ответ 9

script содержащие переменные могут быть импортированы с помощью bash. Рассмотрим script -variable.sh

#!/bin/sh
scr-var=value

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

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

Ответ 10

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

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

    echo $(
        source "${file}";
        eval echo \$\{${variable}\}
    )
}