3

I'm trying to read a config file, and then place the "section" of configs into an array in a bash script, and then run a command off that, and then reitterate through the configs again, and continue to do this until the end of the config file.

Here's a sample config file:

PORT="5000"
USER="nobody"
PATH="1"
OPTIONS=""

PORT="5001"
USER="nobody"
PATH="1"
OPTIONS=""

PORT="5002"
USER="nobody"
PATH="1"
OPTIONS=""

I want the bash script to read in the first "section", bring it into the script, and run the following:
scriptname -p $PORT -u $USER -P $PATH -o $OPTIONS

HOWEVER, I want it to, based on how many "sections" there are in the config file, to take each iteration of a "section", and run the command with its corresponding configuration settings and apply it to the final command. So if it were to read in the config file from above, the output would be:

scriptname -p $PORT -u $USER -P $PATH -o $OPTIONS
scriptname -p $PORT -u $USER -P $PATH -o $OPTIONS
scriptname -p $PORT -u $USER -P $PATH -o $OPTIONS

Which in turn would look like:

scriptname -p 5000 -u nobody -P 1 -o ""
scriptname -p 5001 -u nobody -P 1 -o ""
scriptname -p 5002 -u nobody -P 1 -o ""

Thanks in advance.

2
  • 2
    Since this looks like a mini-language of your own design, do yourself a favor and have something other than whitespace demarcate the logical blocks. Commented Aug 4, 2010 at 22:40
  • Right now, the whitespace blocks will have to do. This is basically a fix for another application - it's temporary, but a quick fix needs to be in place. I'm having to implement this into an init script. The config file needs to be simple. Commented Aug 4, 2010 at 23:16

3 Answers 3

3
#!/bin/bash

if [[ $# -ne 1 ]]; then
    echo "Usage: $0 script.cfg" >&2
    exit 1
fi

function runscript() {
    scriptname -p $PORT -u $USER -P $PATH -o $OPTIONS
}

while read LINE; do
    if [[ -n $LINE ]]; then
        declare "$LINE"
    else
        runscript
    fi
done < "$1"

runscript

If you want to run the scripts in the background simultaneously, try this:

function runscript() {
    nohup scriptname -p $PORT -u $USER -P $PATH -o $OPTIONS &> /dev/null &
}

The & at the end makes them run in the background and nohup ensures they're not killed when the shell exits. The net effect is to turn the scripts into daemons so they'll run continuously in the background regardless of what happens to the parent script.

Sign up to request clarification or add additional context in comments.

4 Comments

I'm actually trying to implement this into a startup script. It works, however, it only runs one instance of the scriptname stanza. I changed the while loop to read in from a config file. Like I said, my mods work, BUT it only starts one program, not the other ones.
Do you mean it only invokes the script once and then quits, or it invokes the script and blocks because the script doesn't exit? If it's the latter I've edited my answer to accommodate. If it's the former I'll need more info on what's not working--the script worked when I tested it with your sample config file.
You should change eval to declare. There are security risks with eval that declare avoids (even though in this case the input file is presumably safe, it's a good habit to change). You'll need to change the logic a bit. Something like [[ -z $LINE ]] && runscript || declare "$LINE"
You don't need nohup if you're using disown
2
#!/bin/bash

awk 'BEGIN{ FS="\n";RS=""}
{
  for(i=1;i<=NF;i++){
   gsub(/.[^=]*=|\042/,"",$i)
  }
  print "scriptname -p "$1" -u "$2" -P "$3" -o "$4
}' file | bash

2 Comments

That's a nice solution. In fact, you could replace print by system and get rid of the | bash.
yes.that's another way provided its not a lot. If its a lot, piping to xargs and bash would be better than calling system().
0

Assuming there is only one empty line between sections:

cat <yourfile> | while read ; do
    if [ -z "$REPLY" ] ; then
        scriptname -p $PORT -u $USER -P $PATH -o "$OPTIONS" 
    else
        eval "$REPLY" # NOTE: eval is evil
    fi
done

2 Comments

That's why you should change eval to declare - it works and it's safer. Oh, and cat is unnecessary. Use done < filename. If nothing else, it saves a call to an external executable.
Thanks for the note on declare, I'll have to remember that. RE: cat -- old habits die hard :).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.