1

I've programmed in other languages but bash and unix in general are very new to me. I think a bash wizard might see an obvious solution, using the source command to read in a settings file - and assign values to my command string?

Ideally I'd like to create a command string from all the field/value settings in a file, by replacing their matches in a string.

My file will look something like:

settings.cfg

#!/bin/bash
#
# WiFi Settings
#
wifi_name=mywifiname
wifi_password=wifi-pwd
#
# Icecast Server Settings
#
icecast_server=icecast.domain.com
icecast_port=443
icecast_mount_url=/user/99999/show/0123456
icecast_show=RPi Demo Show
icecast_user=
icecast_password=icecast-pwd
#
# avconv setting for Raspbian Jessie Lite
# may not need if you're using a self compiled ffmpeg version
#
icecast_legacy=1
#
# Stream Settings - probably not safer to go higher unless great internet connection
#
stream_bitrate=128k

So if I used command:

source settings.cfg

There would be a variable named $stream_bitrate that would have the value of "128k".

I could then use a string replace on stream_parameters= <stream_bitrate> to make that look like stream_parameters= 128k

But I'm wondering if bash gurus can see a simple index based loop - or regular expression that might do the job for whatever parameters are loaded.

I can change my settings file to make it easier if needed. I've put "<>" around the replacement parameter locations - but those can be removed or modified if needed.

And it can be one command line string if needed.

EDIT: Move command line processing to second file

Would this work?

ProcessSettings.sh

#!/bin/bash
#
# Load in config file settings
source settings.cfg

# build command line string
start_cmd=avconv -re -i test.mp3 -c:a libmp3lame -ac 2 -ar 44100 -content_type audio/mpeg -b:a
stream_parameters="$stream_bitrate -f mp3 -ice_name "$icecast_show" -password "icecast_password" -legacy_icecast $icecast_legacy"
icecast_setup=icecast://$icecast_user:$icecast_password@$icecast_server:$icecast_port$icecast_mount_url

stream_cmd = "$start_cmd $stream_parameters $icecast_setup"
9
  • Why not just let the shell dereference the variable? I.e. stream_parameters= $stream_bitrate
    – wjandrea
    Jul 3, 2016 at 2:16
  • So is that the best solution - just rebuild the string inline with the parameters? No loop necessary?
    – dbmitch
    Jul 3, 2016 at 2:19
  • 1
    I don't think you'd even need a second script. Just put the variables that have spaces into quotes, like stream_parameters="$stream_bitrate -f mp3 -ice_name $icecast_show -password $icecast_password -legacy_icecast $icecast_legacy"
    – wjandrea
    Jul 3, 2016 at 2:26
  • 1
    The shell will deref the little vars inside the big var as long as the little vars have been declared first. "little" and "big" have no technical significance, btw.
    – wjandrea
    Jul 3, 2016 at 2:27
  • 1
    I was thinking I'd be getting the cfg file from a different location - so would use source (in a second file) to process it quickly (see updated question)
    – dbmitch
    Jul 3, 2016 at 2:29

1 Answer 1

1

The script in your edit should work perfectly.

But you should note that Bash's variable declaration is picky. I rewrote your code:

# Strings with spaces must be quoted, or the shell will think the second word is a command (-re, in this case).
start_cmd="avconv -re -i test.mp3 -c:a libmp3lame -ac 2 -ar 44100 -content_type audio/mpeg -b:a"

# You can't nest quotes. A quote mark terminates the quotation, unless it's escaped.
stream_parameters="$stream_bitrate -f mp3 -ice_name $icecast_show -password $icecast_password -legacy_icecast $icecast_legacy" 

# It's best to quote strings, as a habit.
icecast_setup="icecast://$icecast_user:$icecast_password@$icecast_server:$icecast_port$icecast_mount_url"

# Don't put spaces around the equals sign.
stream_cmd="$start_cmd $stream_parameters $icecast_setup"

As for how to run a command defined by a string, it's super simple. Just run this: $stream_cmd

Also you might want to state the absolute path of the config file (maybe ~/settings.cfg), unless you want to use the relative location.

4
  • Appreciate the feedback. I'm learning something every day here.
    – dbmitch
    Jul 3, 2016 at 3:05
  • Happy to help !
    – wjandrea
    Jul 3, 2016 at 3:07
  • 1
    You might find shellcheck.net useful. It can check your code, just like I've done here.
    – wjandrea
    Jul 3, 2016 at 3:09
  • Thanks! I will do that for sure. Just uploaded some more bash and udev rules to Code Review for feedback. That's the code for the first step - this here is my second step. codereview.stackexchange.com/questions/133736/…
    – dbmitch
    Jul 3, 2016 at 3:16

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .