2017-06-07 21 views
0

上下文

我在寫一個讀取.config文件的.sh文件。在這個.config文件(我不能編輯)中有一些變量。我想測試這些變量是否定義爲環境變量。如何在bash中使用var檢查現有的環境變量?

config文件:

APPLICATION_PATH=/var/www/application 
MONGO_DATA_PATH=/var/lib/mongodb 
MYSQL_DATA_PATH=/var/lib/mysql 

test.sh文件:

#!/bin/sh 
if test -e ../my_folder/.config      # Test if the .config file exists 
then 
    cat ../my_folder/.config | while read line; do # Read the .config file line per line 

     env_var="${line%=*}"       # Get the part before the '=' character of the current line (e.G. APPLICATION_PATH) 
     echo $env_var        # Display the var (e.G. APPLICATION_PATH) 

                # Here, I would like to display the env var, 
                # e.G. like it would do using echo $APPLICATION_PATH 
                # but using the $env_var 

     ("echo \$$env_var")      # Throw an error 
    done 
fi 

問題

似乎("echo \$$env_var")是不可能的。當我運行test.sh,它會顯示這樣的:

APPLICATION_PATH

./test.sh: ligne 13: echo $APPLICATION_PATH : not found

MONGO_DATA_PATH

./test.sh: ligne 13: echo $MONGO_DATA_PATH : not found

MYSQL_DATA_PATH

./test.sh: ligne 13: echo $MYSQL_DATA_PATH : not found

問題

如何測試是否有使用$env_var環境變量?

+0

便攜,安全,簡單:選擇任意兩個。 – chepner

+0

我聽說如果使用'eval',我肯定會做一件壞事,但在我的情況下,我沒有任何選擇。 – darckcrystale

回答

0

你可以使用這裏提到的方法:Is it possible to build variable names from other variables in bash?

所以相應的代碼會更改爲以下:

#!/bin/sh 
if test -e ../my_folder/.config      
then 
cat ../my_folder/.config | while read line; do 

    env_var="${line%=*}"       
    echo $env_var         
    eval "echo \$$env_var"      # This works 
done 
fi 
+0

它會拋出一個錯誤:'./test.sh:錯誤的替換' – darckcrystale

+0

您可以用「#!/ bin/sh -x」替換第一行,然後運行腳本查看哪一行拋出此錯誤? – jayanth

+0

引發錯誤的行是'echo $ {!env_var}',這是因爲我沒有使用'/ bin/bash',而是'/ bin/sh'。 – darckcrystale

0

如果你可以犧牲便攜性,你應該使用間接參數擴展。可用性和確切的語法因shell而異;這是你會怎麼做在bash

while IFS== read -r varname _; do 
    printf '%s\n' "${!varname}" 
done < ../my_folder/.config 

如果你想犧牲安全,你會做使用eval

while IFS== read -r varname _; do 
    eval "printf '%s\n' \$$varname" 
done < ../my_folder/.config 

犧牲簡單超出堆棧溢出的範圍。但是,一種可能性是使用expr以確保varname只有在使用eval之前包含有效的shell標識符。

while IFS== read -r varname _; do 
    expr "$varname" : '[[:alpha:]_][[:alnum:]_]*' || continue 
    eval "printf '%s\n' \$$varname" 
done < ../my_folder/.config