Bash脚本 – 如何引用variables的文件
嗨我想调用一个variables的设置文件,我怎么能在bash中做到这一点?
所以设置文件将定义variables(例如:CONFIG.FILE):
production="liveschool_joe" playschool="playschool_joe"
脚本将使用这些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
我怎么能bash做这样的事情? 我将不得不使用awk / sed等…?
简短的回答
使用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
命令,并获取和设置“环境variables”也可以完成此操作。
运行export
和echo $ENV
应该是所有你需要知道的访问variables。 访问环境variables的方式与局部variables相同。
要设置它们,请说:
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
命令导入其他脚本:
#!/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
我在安全方面有特别的问题,我在这里find了解决scheme。
我的问题是,我想用一个configuration文件在bash中编写一个部署脚本,其内容像这样的path。
################### 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"
现有的解决scheme由使用“SOURCE”命令组成,并使用这些variables导入configuration文件。 'SOURCE path / to / file'但是这个解决scheme有一些安全问题,因为源文件可以包含Bash脚本可以包含的任何东西。 这会造成安全问题。 当你的脚本正在发送它的configuration文件时,一个恶意软件用户可以“执行”任意代码。
想象一下这样的事情:
################### 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 ~/*
为了解决这个问题,我们可能只想在该文件(variables赋值语法)中只允许NAME=VALUE
forms的结构,也许可以使用注释(尽pipe在技术上,注释并不重要)。 所以,我们可以使用grep -E
egrep
命令检查configuration文件。
这是我如何解决这个问题。
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
在Bash中,input一些命令的输出,而不是文件:
source <(echo vara=3) # variable vara, which is 3 source <(grep yourfilter /path/to/yourfile) # source specific variables
参考
如果正在生成variables而不保存到文件,则不能将它们传送到source
。 看似简单的方法是这样的:
some command | xargs
config.env
var1='foo'
script.sh
export $(cat config.env | grep -v ^# | xargs) echo $var1
将参数文件转换为环境variables
通常我会进行parsing而不是采购,以避免文件中某些工件的复杂性。 它也为我提供了特别处理报价和其他事情的方法。 我的主要目标是保留“=”之后的字面意思,甚至是双引号和空格。
#!/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"
在命令执行过程中双引号会导致参数文件中的双引号被保留。 因此第三个选项也失败了。
另一种select当然就是不提供双引号的variables,如选项4,然后只是为了确保在需要时引用它们。
只是要记住的东西。
实时查询
我喜欢做的另一件事是做一个实时查找,避免使用环境variables:
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}"
不是最有效的,但与较小的文件工作很干净。
包含variables的脚本可以使用bash导入。 考虑一下script-variable.sh
#!/bin/sh scr-var=value
考虑使用variables的实际脚本:
#!/bin/sh bash path/to/script-variable.sh echo "$scr-var"