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"
  • Why not just let the shell dereference the variable? I.e. stream_parameters= $stream_bitrate – wjandrea Jul 3 '16 at 2:16
  • So is that the best solution - just rebuild the string inline with the parameters? No loop necessary? – dbmitch Jul 3 '16 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 '16 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 '16 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 '16 at 2:29
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.

  • Appreciate the feedback. I'm learning something every day here. – dbmitch Jul 3 '16 at 3:05
  • Happy to help ! – wjandrea Jul 3 '16 at 3:07
  • 1
    You might find shellcheck.net useful. It can check your code, just like I've done here. – wjandrea Jul 3 '16 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 '16 at 3:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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