如何使用 Bash 引用文件中的变量?

发布于 2024-10-20 13:14:09 字数 565 浏览 2 评论 0原文

我想调用变量的设置文件。我怎样才能在 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 等?

I want to call a settings file for a variable. How can I do this in Bash?

The settings file will define the variables (for example, CONFIG.FILE):

production="liveschool_joe"
playschool="playschool_joe"

And the script will use these variables in it:

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

How can I get Bash to do something like that? Will I have to use AWK, sed, etc.?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

伊面 2024-10-27 13:14:09

简短的回答

使用 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 命令,获取和设置“环境变量”也可以实现此目的。

关于访问变量,您只需要了解运行 exportecho $ENV 即可。访问环境变量的方式与访问局部变量的方式相同。

要设置它们,请说:

export variable=value

在命令行。所有脚本都可以访问该值。

The short answer

Use the source command.


An example using source

For example:

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

Note that the output from sh ./script.sh in this example is:

~$ sh ./script.sh 
playschool_joe
liveschool_joe

This is because the source command actually runs the program. Everything in config.sh is executed.


Another way

You could use the built-in export command and getting and setting "environment variables" can also accomplish this.

Running export and echo $ENV should be all you need to know about accessing variables. Accessing environment variables is done the same way as a local variable.

To set them, say:

export variable=value

at the command line. All scripts will be able to access this value.

梦里梦着梦中梦 2024-10-27 13:14:09

使用点甚至更短(采购):

#!/bin/bash
. CONFIG_FILE

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

Even shorter using the dot (sourcing):

#!/bin/bash
. CONFIG_FILE

sudo -u wwwrun svn up /srv/www/htdocs/$production
sudo -u wwwrun svn up /srv/www/htdocs/$playschool
孤凫 2024-10-27 13:14:09

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

Use the source command to import other 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
爱要勇敢去追 2024-10-27 13:14:09

在 Bash 中,要获取某些命令的输出而不是文件:

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

参考

in Bash, to source some command's output, instead of a file:

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

reference

终陌 2024-10-27 13:14:09

我遇到了同样的问题,特别是在安全方面,我在此处找到了解决方案。

我的问题是我想在 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”命令并导入包含这些变量的配置文件。 'SOURCE path/to/file'

但是这个解决方案存在一些安全问题,因为源文件可以包含 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

I have the same problem specially in case of security and I found the solution here.

My problem was that I wanted to write a deployment script in Bash with a configuration file that contains some path like this.

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

An existing solution consists of use "SOURCE" command and import the configuration file with these variables. 'SOURCE path/to/file'

But this solution has some security problems, because the sourced file can contain anything a Bash script can.

That creates security issues. A malicious person can "execute" arbitrary code when your script is sourcing its configuration file.

Imagine something like this:

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

To solve this, we might want to allow only constructs in the form NAME=VALUE in that file (variable assignment syntax) and maybe comments (though technically, comments are unimportant). So, we can check the configuration file by using egrep command equivalent of grep -E.

This is how I have solve the issue.

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
上课铃就是安魂曲 2024-10-27 13:14:09

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

通常我会进行解析而不是采购,以避免文件中某些工件的复杂性。它还为我提供了专门处理报价和其他事情的方法。我的主要目标是将“=”后面的所有内容保留为文字,甚至包括双引号和空格。

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

不是最有效的,但对于较小的文件工作得非常干净。

Converting a parameter file to environment variables

Usually I go about parsing instead of sourcing, to avoid complexities of certain artifacts in my file. It also offers me ways to specially handle quotes and other things. My main aim is to keep whatever comes after the '=' as a literal, even the double quotes and spaces.

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

Note the little trick I had to do to consider my quoted text as a single parameter with space to my cntpars function. There was one extra level of evaluation required. If I wouldn't do this, as in option 2, I would have passed two parameters as follows:

  • "value
  • content"

Double quoting during command execution causes the double quotes from the parameter file to be kept. Hence the 3rd Option also fails.

The other option would be of course to just simply not provide variables in double quotes, as in option 4, and then just to make sure that you quote them when needed.

Just something to keep in mind.

Real-time lookup

Another thing I like to do is to do a real-time lookup, avoiding the use of environment 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}"

Not the most efficient, but with smaller files works very cleanly.

软甜啾 2024-10-27 13:14:09

如果正在生成变量但未将其保存到文件中,则无法将它们通过管道传送到 source 中。看似简单的方法是这样的:

some command | xargs

If the variables are being generated and not saved to a file you cannot pipe them in into source. The deceptively simple way to do it is this:

some command | xargs
楠木可依 2024-10-27 13:14:09

为了防止命名冲突,仅导入您需要的变量:

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

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

For preventing naming conflicts, only import the variables that you need:

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

    echo $(
        source "${file}";
        eval echo \$\{${variable}\}
    )
}
最单纯的乌龟 2024-10-27 13:14:09

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

考虑 script-variable.sh 文件:

#!/bin/sh
scr-var=value

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

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

The script containing variables can be executed imported using Bash.

Consider the script-variable.sh file:

#!/bin/sh
scr-var=value

Consider the actual script where the variable will be used:

 #!/bin/sh
 bash path/to/script-variable.sh
 echo "$scr-var"
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文