Sign up ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It's 100% free, no registration required.

I need to create a config file for my own script: here an example:

script:

#!/bin/bash
source /home/myuser/test/config
echo "Name=$nam" >&2
echo "Surname=$sur" >&2

Content of /home/myuser/test/config:

nam="Mark"
sur="Brown"

that's works!

My question: is this the correct way to do this or there're other ways?

share|improve this question
    
bad example (mine) I've corrected my question. Thanks –  Pol Hallen Dec 23 '14 at 17:00
    
The variables should be at the top. I'm surprised it works. Anyway, why do you need a config file? Are you planning to use these variables somewhere else? –  Faheem Mitha Dec 23 '14 at 17:01
    
Faheem, I need the variables because my script has many options: using a config file will semplify the script. Thanks –  Pol Hallen Dec 23 '14 at 17:05
4  
IMHO its fine. I would do this way. –  Tinti Dec 23 '14 at 17:11
    
abcde also does it this way and that is a quite big program (for a shell script). You can have a look at it here. –  Lucas Dec 23 '14 at 21:04

3 Answers 3

source is not secure as it will execute arbitrary code. This may not be a concern for you, but if file permissions are incorrect, it may be possible for an attacker with filesystem access to execute code as a privileged user by injecting code into a config file loaded by an otherwise-secured script such as an init script.

So far, the best solution I've been able to identify is the clumsy reinventing-the-wheel solution:

myfile.conf

username=foo
password=bar
echo rm -rf /
PS1=h4xx0r3d
hostname=localhost; echo rm -rf /

Using source, this would run echo rm -rf / twice, as well as change the running user's PS1. Instead, do this:

myscript.sh

#!/bin/bash
typeset -A config # init array
config=( # set default values in config array
    [username]="root"
    [password]=""
    [hostname]="localhost"
)

while read line
do
    if echo $line | grep -F = &>/dev/null
    then
        varname=$(echo "$line" | cut -d '=' -f 1)
        config[$varname]=$(echo "$line" | cut -d '=' -f 2-)
    fi
done < myscript.conf

echo ${config[username]} # should be loaded from config file
echo ${config[password]} # should be loaded from config file
echo ${config[hostname]} # includes the "injected" code, but in our array it's no threat
echo ${config[PS1]} # also respects variables that you may not have been looking for,
                    # but they're sandboxed inside the $config array

I hope this helps. Please reply if you find a security exploit in my code.

share|improve this answer

You can do it:

#!/bin/bash
name="mohsen"
age=35
cat > /home/myuser/test/config << EOF
Name=$name
Age=$age
EOF
share|improve this answer

The most common, efficient and correct way is to use source, or . as a shorthand form. For example:

source /home/myuser/test/config

or

. /home/myuser/test/config

Something to consider, however, is the security issues that using an additional externally-sourced configuration file can raise, given that additional code can be inserted. For more information, including on how to detect and resolve this issue, I would recommend taking a look at the 'Secure it' section of http://wiki.bash-hackers.org/howto/conffile#secure_it

share|improve this answer
    
I had high hopes for that article (came up in my search results too), but the author's suggestion of attempting to use regex to filter out malicious code is an exercise in futility. –  Mikkel May 28 at 23:02

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.