Bashを使用して変数のファイルを参照する方法


151

変数の設定ファイルを呼び出したいのですが、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などを使用する必要がありますか?

回答:


241

短い答え

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

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


これを機能させるには、config.shに実行権限が必要ですか?
Ramiro 2014年

2
sourceファイルを提供するのではなく、コンテンツをパイプして使用する方法はありますか?Like some command | sourceは機能しません...
Elliot Chance

1
気にしないで、私は解決策を見つけて他の人に投稿しました。
Elliot Chance

配列を復元するには、各配列のエントリ値を個別に格納する必要があります(からの配列全体を1行declare -pではなく)などsomeArray[3]="abc"、次のようになります...
Aquarius Power

1
@Ramiroいいえ、ありません。私はチェックした。:)
Matt Komarnicki 2017

22

ドットを使用するとさらに短くなります:

#!/bin/bash
. CONFIG_FILE

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

17
スクリプトでこれを使用する場合、省略表現は不要であり、混乱を招く可能性があります。完全なsourceコマンドを使用してそれを明確にしてみませんか?
Lyle

2
@Lyle必要のないときに、スクリプトが移植可能なPOSIX構文から不必要に逸脱しないようにしたいのですか。
tripleee

14

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

12

私は特にセキュリティのcasで同じ問題を抱えており、ここで解決策を見つけました。

私の問題は、このようなパスを含む構成ファイルを使用して、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に、ファイル内の形式のコンストラクト(変数代入構文)とコメント(技術的にはコメントは重要ではありません)のみを許可することができます。したがって、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

1
構文チェッカーを検証して、すべてのケースが正しく説明されていることを確認していませんが、セキュリティの問題があるため、これは断然最善の方法です。
アンジェロ

6
それは十分に安全ではありません、あなたはまだ行うことができますCMD="$(rm -fr ~/*)"
svlasov 2017年

おかげで私はそれが深刻な問題だと思う、@svlasov、私のようなコマンドsubtitutionのために使用される文字を拒絶することによって、問題の種類を回避するために、私の答えを編集して(、 `` `最終と CONFIG_SYNTAX="(^\s*#|^\s*$|^\s*[a-z_][^[:space:]]*=[^;&\(`]*$)"
エルマン

まだ十分ではありません。foo=bar unleash_virus実行できます。注意してくださいfoo=bar\ unleash_virusfoo="bar unleash_virus"そしてfoo=bar #unleash_virus安全です。特にすべての可能な引用とエスケープについて考えるとき、適切にサニタイズし、とにかくいくつかの無害な構文をブロックしないのは簡単ではありません。
Kamil Maciorowski

9

Bashで、ファイルの代わりにコマンドの出力をソースするには:

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

参照


3

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

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

#!/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番目のオプションも失敗します。

他のオプションはもちろん、オプション4のように、単に変数を二重引用符で囲まないで、必要に応じて変数を必ず引用することです。

心に留めておくべきこと。

リアルタイム検索

私がやりたいもう1つのことは、環境変数の使用を避けて、リアルタイムの検索を行うことです。

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

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


2

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

some command | xargs

-1

変数を含むスクリプトは、bashを使用してインポートして実行できます。script-variable.shを検討してください。

#!/bin/sh
scr-var=value

変数が使用される実際のスクリプトを検討してください:

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

これは機能せず、サブプロセスでBashスクリプトを実行し、その存続期間中に作成した環境(変数を含む)をすべて失います。またsrc-var、有効な識別子ではありません。
tripleee

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.