如何使用 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 做这样的事情呢? 我必须使用 AWKSed等等吗?

216975 次浏览

使用 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

简短的回答

使用 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命令实际上运行程序。


另一种方式

您可以使用内置的 export命令,获取和设置“环境变量”也可以实现这一点。

运行 exportecho $ENV应该是您所需要了解的关于访问变量的全部内容。访问环境变量的方法与访问局部变量的方法相同。

要设定它们,请说:

export variable=value

所有脚本都可以访问这个值。

使用点(采购)更短:

#!/bin/bash
. CONFIG_FILE


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

如果生成的变量没有保存到文件中,则不能将它们导入到 source中。看似简单的方法是这样的:

some command | xargs

在 Bash 中,来源于某个命令的输出,而不是一个文件:

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

参考文献

我有同样的问题,特别是在安全的情况下,我找到了解决方案 给你

我的问题是,我希望在 Bash 中编写一个部署脚本,其配置文件包含类似下面这样的路径。

################### Configuration 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”命令并导入带有这些变量的配置文件

但是这个解决方案存在一些安全问题,因为源文件可以包含任何 Bash 脚本可以包含的内容。

当你的脚本正在寻找它的配置文件时,一个恶意的人可以“执行”任意的代码。

想象一下这样的事情:

 ################### Configuration 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形式的构造(变量赋值语法) ,也可以使用注释(尽管从技术上讲,注释并不重要)。因此,我们可以使用相当于 grep -Eegrep命令来检查配置文件。

这就是我解决问题的方法。

configfile='deployment.cfg'
if [ -f ${configfile} ]; then
echo "Reading user configuration...." >&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 "The configuration file is unclean. Please clean 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

将参数文件转换为环境变量

通常我会进行解析而不是源代码,以避免文件中某些工件的复杂性。它还为我提供了特别处理报价和其他事情的方法。我的主要目的是将’=’后面的任何内容保留为文字,甚至包括双引号和空格。

#!/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中那样,我将传递两个参数,如下所示:

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

虽然不是最高效的,但是使用较小的文件工作起来非常干净。

可以使用 Bash 导入包含变量的脚本。

考虑 Script-variable.sh文件:

#!/bin/sh
scr-var=value

考虑一下使用变量的实际脚本:

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

为了防止命名冲突,只导入所需的变量:

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


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