0

I have the following script sub.sh:

#!/bin/sh

. ./sub.conf

echo $topic

mosquitto_sub -u $user -P $password -h $server -t $topic

And the associated settings file sub.conf:

topic="#"             #-t
user="mqtt"           #-u
password="mqttpass"   #-P
server="127.0.0.1"    #-h

I’d like to find a way to call my script and override any values that are passed in that are used in the sub.conf file. Example:

./sub.sh -t foobar

Would use all of the values in the .conf file except $topic would equal foobar instead of #. This would require somehow mapping the command line argument -t to $topic. I realized writing this could quickly spiral into a lot more code than I want to write. Instead of reinventing the wheel, I figured someone has written something similar.

1

There's a reasonably simple way if

  1. You use bash, ksh or similarly advanced shells
  2. You change your intended syntax a bit.

With;

#!/bin/bash

. ./sub.conf
[ -n "$1" ] && declare "$@" # use arguments to set variables
echo $topic

mosquitto_sub -u $user -P $password -h $server -t $topic

You can do;

./sub.sh topic='#'

Example:

$ bash -c 'foo=1; declare "$@"; echo $baz $foo' _ foo=bar baz=fo
fo bar
1

There is no ready-to-go solution you can call with just one string. However you can use things like getopts or similar.

This is an example to get -t and -u options in bash:

#!/bin/bash
while getopts ":t:u:" OPTION; do
    case "$OPTION" in
        t)  echo topic="$OPTARG" ;;
        u)  echo user="$OPTARG" ;;
    esac
done

This is a very least you have to add to your script.

You also might want to consider libraries like shflags, but that doesn't seem to simplify the thing anyway.

1

I found a pretty good script builder site called Argbash. You feed it a "template" which will build a skeleton script for you. For my example, create a file in your user home directory ~/sub.conf with your default values:

topic="#"
user="mqtt"
password="mqttpass"
server="127.0.0.1"

Next, go to argbash's template creation page and feed it this template:

#!/bin/bash
# version="0.1"
#
# This is an optional arguments-only example of Argbash potential
#
# ARG_OPTIONAL_SINGLE([user], [u], [optional argument help msg])
# ARG_OPTIONAL_SINGLE([Password], [P], [optional argument help msg])
# ARG_OPTIONAL_SINGLE([server], [s], [optional argument help msg])
# ARG_OPTIONAL_SINGLE([topic], [t], [optional argument help msg])
# ARG_HELP([The general script's help msg])
# ARGBASH_GO

# [ <-- needed because of Argbash

echo "Value of --user: $_arg_user"
echo "Value of --Password: $_arg_password"
echo "Value of --server: $_arg_server"
echo "Value of --topic: $_arg_topic"

# ] <-- needed because of Argbash

And then click the "GENERATE SCRIPT NOW" button. It will generate a script for you which you can then download. Inside of that script search for:

# THE DEFAULTS INITIALIZATION - OPTIONALS
_arg_user=
_arg_password=
_arg_server=
_arg_topic=

Simply change that to:

# THE DEFAULTS INITIALIZATION - OPTIONALS
. ~/.sub.conf
_arg_user=$user
_arg_password=$password
_arg_server=$server
_arg_topic=$topic

. ~/.sub.conf will load the values from your config file into the variables specified in that file. The following lines will populate each command line argument you specified in your template. Any values that are passed into your script will override those default values. You can remove the echo "Value of --user: $_arg_user statements if you wish. At the very end of the script, simply consume the arguments, such as:

mosquitto_sub -u $_arg_user -P $_arg_password -h $_arg_server -t $_arg_topic

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.