0

I'm currently stuck on how to do the following:

I have a settings file that looks like this:

USER_ID=12
ROLE=admin
STARTED=10/20/2010
...

I need to access the role and map the role to one of the variables in the script below. After I will use that variable to call open a doc with the correct name.

test.sh

#!/bin/sh

ADMIN=master_doc
STAFF=staff_doc
GUEST=welcome_doc    

echo "accessing role type"
cd /setting

#open `settings` file to access role?
#call correct service
#chmod 555 master_doc.service 

Is there a way to interpolate strings using bash like there is in javascript? Also, I'm guessing I would need to traverse through the settings file to access role?

lost9123193
  • 10,460
  • 26
  • 73
  • 113
  • Your script doesn't actually use any variables like `$admin`, so what are you trying to accomplish exactly? If `admin = master_doc` is supposed to be assignment, the spaces shouldn't be there. Please [edit] to clarify. – wjandrea Aug 10 '20 at 23:27
  • @wjandrea the settings has a role. That role needs to be mapped to a doc name which is then used to call a specific service. – lost9123193 Aug 10 '20 at 23:34
  • Oh, I get what you mean. You want to get the variables from `settings`, use `$role` as an indirect reference to `$admin`, i.e. `master_doc`, then turn that into a string, `master_doc.service`. I'll write you answer. – wjandrea Aug 10 '20 at 23:35
  • @lost9123193 : There is no bash involved in your question, since your script seems to be `sh`, not `bash`. Also you did not define the syntax of your _settings_ file. The example you povided, would be valid syntax in both sh and in bash, so a `source settings` would be enough to read the variables in your concrete example. – user1934428 Aug 11 '20 at 06:21

4 Answers4

5

With bash and grep and assuming that the settings file has exactly one line beginning with ROLE=:

#!/bin/bash

admin=master_doc
staff=staff_doc
guest=welcome_doc

cd /setting || exit
role=$(grep '^ROLE=' settings)
role=${role#*=}
echo chmod 555 "${!role}.service"

Drop the echo after making sure it works as intended.
Look into Shell Parameter Expansion for indirect expansion.

M. Nejat Aydin
  • 9,597
  • 1
  • 7
  • 17
  • could you explain what this means? ${role#*=}? – lost9123193 Aug 11 '20 at 17:01
  • @lost9123193 The part from the beginning up to (and including) the first `=` character is deleted from the value of the variable `role`. Look into [Shell Parameter Expansion](https://www.gnu.org/savannah-checkouts/gnu/bash/manual/bash.html#Shell-Parameter-Expansion) for`${parameter#word}` and `${parameter##word}` – M. Nejat Aydin Aug 11 '20 at 17:17
3

From what I understand, you want to get the variables from settings, use $role as an indirect reference to $admin, i.e. master_doc, then turn that into a string, master_doc.service.

Firstly, instead of indirection, I recommend an associative array since it's cleaner.

You can use source to get variables from another file, as well as functions and other stuff.

Lastly, to dereference a variable, you need to use the dollar sign, like $role. Variable references are expanded inside double-quotes, so that's sort of the equivalent of string interpolation.

#!/bin/bash

# Associative array with doc names
declare -A docs=(
    [admin]=master_doc
    [staff]=staff_doc
    [guest]=welcome_doc
) 

echo "accessing role type"
cd setting || exit

source settings  # Import variables 
true "${ROLE?}"  # Exit if unset

echo chmod 555 "${docs[$ROLE]}.service"  # Select from associative array
# ^ Using "echo" to test. Remove if the script works properly.
wjandrea
  • 28,235
  • 9
  • 60
  • 81
0

You can source the settings file to load the variables:

source settings

And then you can use them in your script:

chmod 555 "${admin}.service"  # will replace ${admin} with master_doc
Enrico
  • 766
  • 8
  • 19
  • The quotes around variable names are to avoid splitting parameters. For example, if your variable were `x="foo bar.sh"` and you then do `chmod 555 $x` (without quoting `x`), it will expand $x to `chmod 555 foo bar.sh`, which will try to apply `chmod 555` to a file `foo` and another file `bar.sh`. If you quote it (`chmod 555 "$x"`), then it will correctly point to `foo bar.sh` (one file). – Enrico Aug 10 '20 at 23:26
  • Also: you can call variables with braces or without them (so `$x` and `${x}` are both valid). I prefer to use braces so it's easier to identify var names. – Enrico Aug 10 '20 at 23:27
  • It appears you may have misunderstood the question. – Lxer Lx Aug 11 '20 at 00:23
  • @LxerLx thanks for the heads up, it seems like OP changed/added details to the question after I answered. With that said, given an example settings file like the one in this question, this answer would be valid :) – Enrico Aug 11 '20 at 11:30
  • 1
    The answer is valid when`ROLE=admin`, but is not valid when `ROLE=guest` or`ROLE=stuff`. The OP wants that the script behaves according to the value of `ROLE`. I still suspect you may have misunderstood the question. – Lxer Lx Aug 11 '20 at 17:32
0

I'd certainly use source(.)

#!/bin/sh
ADMIN=master_doc
STAFF=staff_doc
GUEST=welcome_doc

echo "accessing role type"
. /setting/settings 2> /dev/null || { echo 'Settings file not found!'; exit 1; }

role=${ROLE^^} # upercase rolename
echo ${!role}.service # test echo
Ivan
  • 6,188
  • 1
  • 16
  • 23