简体   繁体   中英

How to check existing environment variable using a var in bash?

Context

I am writting a .sh file which read a .config file. In this .config file (which I can't edit) there are some variables. I want to test if those variables are defined as environment variables.

.config file:

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

test.sh file:

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

Problem

It seems that ( "echo \\$$env_var" ) is not possible. When I run test.sh, it displays this:

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

Question

How can I test if there is an environment variable using $env_var ?

You could use the method mentioned here: Is it possible to build variable names from other variables in bash?

So accordingly your code would change to the following:

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

If you can sacrifice portability, you should use indirect parameter expansion. The availability and exact syntax varies from shell to shell; this is how you would do it in bash :

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

If you want to sacrifice safety, you would do use eval :

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

Sacrificing simplicity is beyond the scope of Stack Overflow. One possibility, though, is to use expr to ensure that varname only contains a valid shell identifier before using eval .

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM