web-dev-qa-db-ja.com

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などを使用する必要がありますか?

128
edumike

短い答え

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

コマンドラインで。すべてのスクリプトはこの値にアクセスできます。

209
Ezra

ドットを使用してさらに短く:

#!/bin/bash
. CONFIG_FILE

Sudo -u wwwrun svn up /srv/www/htdocs/$production
Sudo -u wwwrun svn up /srv/www/htdocs/$playschool
22
artistoex

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
13
Daniel

セキュリティのcasで特に同じ問題があり、解決策を見つけました here

私の問題は、このようなパスを含む構成ファイルを使用して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 path/to/file'ただし、ソースファイルには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"; rm -fr ~/*

    # hey look, weird code follows...
    echo "I am the skull virus..."
    echo rm -fr ~/*

これを解決するために、そのファイルではNAME=VALUEという形式の構造(変数割り当て構文)とコメント(おそらく技術的には重要ではありません)のみを許可することができます。そのため、grep -Eと同等のegrepコマンドを使用して、構成ファイルを確認できます。

これが問題の解決方法です。

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
11
Erman

bashで、ファイルの代わりにコマンドの出力を取得するには:

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

参照

7
zhazha

パラメータファイルを環境変数に変換する

通常、ファイル内の特定のアーティファクトの複雑さを回避するために、ソースではなく構文解析を行います。また、引用符などを特別に処理する方法も提供します。私の主な目的は、 '='の後に続く文字列を、二重引用符やスペースも含めてリテラルとして保持することです。

#!/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関数へのスペースを持つ単一のパラメーターとして引用テキストを考慮するために私がしなければならなかった小さなトリックに注意してください。評価の追加レベルが1つ必要でした。オプション2のようにこれを行わない場合、次のように2つのパラメーターを渡します。

  • "value
  • content"

コマンドの実行中に二重引用符を使用すると、パラメーターファイルからの二重引用符が保持されます。したがって、3番目のオプションも失敗します。

もう1つのオプションは、オプション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}"

最も効率的ではありませんが、より小さいファイルで非常にきれいに動作します。

3
YoYo

変数が生成されていて、ファイルに保存されていない場合、sourceにパイプすることはできません。それを行う一見シンプルな方法はこれです:

some command | xargs
2
Elliot Chance